views:

971

answers:

5

I'm trying to write up the LINQ statement that is equivalent to:

select e.EmployeeID, EmployeeName = e.FirstName + ' ' + e.LastName
from Employees e
where e.EmployeeID not in
(
    select EmployeeID from Managers
)

I think I'm pretty close with the following:

from e in Employees
where e.EmployeeID !=    // This is where I'm lost
(
    from m in Managers select m.EmployeeID
)
select new
{
    e.EmployeeID,
    EmployeeName = e.FirstName + ' ' + e.LastName
}

I'm trying to put this into a Html.DropDownList.

A: 

Use the .Contains() method and insert an ! creating a NOT style syntax.

This would be {collection}.Contains(this != to that);

This may be of interest to you too: http://srtsolutions.com/blogs/billwagner/archive/2006/04/10/linq-samples-part-11.aspx

Andrew Siemer
+3  A: 

I'm not exactly sure what the proper query notation for this is, but the following expanded syntax will get the job done

var result = Employees
  .Where( e => !Managers.Where(m => m.EmployeeId == e.EmployeeId).Any())
  .Select( e => new { EmployeeId = e.EmployeeId, EmployeeName = e.FirstName + ' ' + e.LastName);
JaredPar
While this surely works it should be noted that depending on how the query gets executed and (not) optimized it *might* have a terrible performance.
emaster70
@emaster70, I think the best way to describe it is that it has E*M performance in Big O notation.
JaredPar
A: 

Here is an article about using the IN statement with LINQ. With a little elbow grease I'm sure you could modify the technique to do a NOT IN.

http://blogs.msdn.com/alexj/archive/2009/03/26/tip-8-writing-where-in-style-queries-using-linq-to-entities.aspx

AJ
+3  A: 

Using Any:

from e in Employees
where !Managers.Any(m => m.EmployeeID == e.EmployeeID)
select new
{
    e.EmployeeID,
    EmployeeName = e.FirstName + ' ' + e.LastName
}

Or, using a left join:

from e in Employees
join m in Managers on e.EmployeeID equals m.EmployeeID into managerGroup
from m in managerGroup.DefaultIfEmpty()
where m == null
select new
{
    e.EmployeeID,
    EmployeeName = e.FirstName + ' ' + e.LastName
}
Bryan Watts
A: 

You can get the result you want with a fluid implementation of Linq.Except():

List<Employee> employees = new List<Employee>
    {
     new Employee { EmployeeID = 1, FirstName = "John", LastName = "Smith" },
     new Employee { EmployeeID = 2, FirstName = "Jane", LastName = "Doe" },
     new Employee { EmployeeID = 3, FirstName = "Eddie", LastName = "Punchclock" }
    };
List<Employee> managers = new List<Employee>
    {
     new Employee { EmployeeID = 2, FirstName = "Jane", LastName = "Doe" },
    };
var nonManagerEmployees = employees.Except(managers, x => x.EmployeeID)
    .Select(x => new
     {
      x.EmployeeID,
      EmployeeName = x.FirstName + " " + x.LastName
     });

foreach(var entry in nonManagerEmployees)
{
    Console.WriteLine(entry.EmployeeID+" "+entry.EmployeeName);
}

output:

1 John Smith
3 Eddie Punchclock
Handcraftsman