views:

52

answers:

1

I have a query that looks like this:

    var results = from person
                  where <here I need to do something like if person is of type 
Employee, call person.GetSalary() > 100000 but if the person is of type Contractor, I need to execute 
several lines of code before doing a person.GetSalary() > 100000 
                  select new {person.Name}

The difficulty is in constructing the where clause. Can someone help me complete this query?

+3  A: 

You can always write a method that performs your logical check and call it in a separate where clause. To do so with LINQ-to-Entities, you must first materialize the results using AsEnumerable():

bool CheckEmployeeOrContractorSalary( Person p, decimal salaryLevel )
{
   // put your employee and contractor logic here...
   if( p is Employee ) {
       return p.GetSalary() > salaryLevel; }
   else if( p is Contractor ) {
       // ... your complex logic...
       return p.GetSalary() > salaryLevel; }
   else
       // ??? 
       return false;
}

Now you can write:

var results = from person in (
                  (from p in person select new { p.Name } ).AsEnumerable())
              where CheckEmployeeOrContractorSalary( person, 100000 )
              select new {person.Name};
LBushkin
The question is tagged "Linq to Entities"; a custom method won't be convertible to SQL, so if you do that you need to filter the results locally (by calling AsEnumerable before the Where)
Thomas Levesque
@Thomas - Can you elaborate why this solution wouldn't work and yes it is Linq to Entities.
DotnetDude
A different question I have is - how to I debug linq queries? Say I have a really long linq query with a bunch of wheres and joins and lets and I need to put the breakpoint on one of the lines to check the values. It appears that this is not possible.
DotnetDude
@DotnetDude, Linq to Entities queries are translated to SQL and executed on the database. So you can only use constructs and methods that are recognized by the query generator, which of course is not the case of the CheckEmployeeOrContractorSalary method. Regarding debug, you can't put breakpoints inside a Linq query because, as I said, it is not executed locally but on the database
Thomas Levesque
**@Thomas Levesque:** You are correct. I missed that tag. I'll edit my response. **@DotnetDude:** Debugging LINQ can be a bit tricky. You can still put a break point in any method or expression within a LINQ-to-objects query, but realize that you will only hit those breakpoints as you begin enumerating results. Debugging into things like joins and selects within a LINQ query isn't really possible - as the implementation is hidden within the behavior of the Enumerable class. When possible, one approach is to build up a complex query from a simpler query that works.
LBushkin
It should also be noted that this solution moves all filtering logic to memory. So *all* person names will be from the database, which is a potentially big performance problem.
jeroenh