Marcus
Marcus

Reputation: 5447

Conditional Operator without evaluating twice?

Say I have the following:

MyDate = 
  (db.MyTables.FirstOrDefault(x => x.MyID == idToFind).DateValue == DateTime.MinValue) 
    ? DateTime.Now 
    : db.MyTables.FirstOrDefault(x => x.MyID == idToFind).DateValue

Is there any way to do this without running that LINQ query twice?
I cannot run it first into a temp variable because this query is itself part of a bigger LINQ query.

Upvotes: 3

Views: 271

Answers (5)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112352

Use LINQ's let statement

from a in someSource
let d = db.MyTables.FirstOrDefault(x => x.MyID == a.idToFind).DateValue
select (d == DateTime.MinValue) ? DateTime.Now : d;

Upvotes: 0

BrokenGlass
BrokenGlass

Reputation: 160902

I cannot run it first into a temp variable because this query is itself part of a bigger LINQ query.

You can use a let assignment within your query (or alternatively a projection that includes a helper field if you are using lambda syntax - that's what it gets compiled down to anyway):

var query = from foo in db.Bar
            let bar = db.MyTables.FirstOrDefault(x => x.MyID == idToFind).DateValue
            select  new 
            {
               MyDate = bar == DateTime.MinValue ? DateTime.Now : bar
            }

Upvotes: 7

Mattias Isegran Bergander
Mattias Isegran Bergander

Reputation: 11909

You can still use a temporary variable, declare it but assign it inside that expression. Lots of code might make it hard to read in some situations, but at least reduces duplication.

MyDate = 
  (temp = db.MyTables.FirstOrDefault(x => x.MyID == idToFind).DateValue) == DateTime.MinValue) 
    ? DateTime.Now 
    : temp

Upvotes: 0

Oded
Oded

Reputation: 499002

Evaluate once and assign to a variable - use the variable in your conditional:

var item = db.MyTables.FirstOrDefault(x => x.MyID == idToFind);

MyDate = (item.DateValue == DateTime.MinValue) 
    ? DateTime.Now 
    : item.DateValue

Or:

var theDate = db.MyTables.FirstOrDefault(x => x.MyID == idToFind).DateValue;

MyDate = (theDate == DateTime.MinValue) 
    ? DateTime.Now 
    : theDate

Upvotes: 1

Tejs
Tejs

Reputation: 41246

Yes.

var dateValue = db.MyTables.FirstOrDefault(x => x.MyID == idToFind).DateValue;

return dateValue == DateTime.MinValue ? DateTime.Now : dateValue;

Now, when you're saying that the value can't be stuffed into a temp value, what do you mean? The above code certainly looks to be able to converted to that pattern.

Upvotes: 2

Related Questions