Can a conditional LINQ query be combined into one that runs every time?

I've got two queries used to filter down a list of data. The main part runs every time, and in normal situations should cut the total number of results down to at most a dozen or two. When I'm editing a Foo object instead of creating a new one, I also want to remove the copy saved in the DB from the set of data I'm working on.

I'm currently using an if statement and a second query to strip it out. Is there a way to combine the condition and second query into the first one?

IEnumerable<Foo> myFoos = bar.GetFoos()
    .Where(f => f.Value1 == value1 && f.Value2 == value2);


if (editFoo != null)
   myFoos = myFoos.Where(f => f.ID != editFoo.ID);

When I try the queries suggested by sehe or Dan Seaver, and call .ToList() on myFoos I get an exception:

Unable to create a constant value of type 'Foo'. Only primitive types ('such as Int32, String, and Guid') are supported in this context

I created dummy objects that contained every property in my un-munged query and it ran without error, so I'm leaning towards suspecting the problem is that the Entity Framework doesn't understand the null checks in the proposed queries and is barfing on them. The entity framework was to blame; without it either solution would work as written.

Upvotes: 1

Views: 120

Answers (2)

sehe
sehe

Reputation: 393557

Boolean logic to the rescue.

IEnumerable<Foo> myFoos = bar.GetFoos()
    .Where(f => 
        (f.Value1 == value1) && 
        (f.Value2 == value2) &&
        ((editFoo == null) || (f.ID != editFoo.ID)));

The thing that makes it work is shortcut evaluation

Upvotes: 3

Dan McClain
Dan McClain

Reputation: 11920

You could do something like:

IEnumerable<Foo> myFoos = bar.GetFoos()
    .Where(f => f.Value1 == value1 &&
           f.Value2 == value2 && 
           ((editFoo != null) ? (f.ID != editFoo.ID) : true) );

Upvotes: 1

Related Questions