如何使用Entity Framework处理多对多关系?

时间:2009-08-11 12:18:24

标签: linq entity-framework many-to-many

我有一个包含3个表的SampleDB。

Table Employees (EmployeeID, EmployeeName)
Table Projects (ProjectID, ProjectName)
Table ProjectResources (ProjectID, EmployeeID)

ProjectResources表是交叉引用表,用于在Employees和Projects之间创建多对多关系。

我想使用LINQ来选择尚未分配给特定项目的所有员工。以下是我采取的步骤:

  1. 使用Entity Framework向导从上面的SampleDB创建实体数据模型。该向导创建了两个实体:Employees和Projects,我将其重命名为Employee和Project。 Project实体具有Employees导航属性,该属性引用Employees集合,Employee实体具有引用Projects集合的Projects导航属性。因此,看起来好像EF已经正确识别了Employees和Projects表之间的多对多关系。

  2. 现在这里是我用来尝试选择尚未分配给项目的所有员工的代码。

        SampleDBEntities db = new SampleDBEntities();
        var project = db.Projects.Include("Employees")
                                 .FirstOrDefault(p => p.ProjectID == 1);
        var currentEmployees = project.Employees;
        var employeesNotAssignedToProject = 
                db.Employees.Except(currentEmployees);
    
  3. 使用ProjectID为1的Project,

    var项目加载正常 var currentEmployees使用当前分配给该项目的Employees列表正确加载

    当我尝试在监视窗口中观察员工的结果视图时,我得到以下异常:

      

    {“无法创建类型为'System.Collections.Generic.IEnumerable`1'的常量值。   在此上下文中仅支持原始类型(例如Int32,String和Guid')。“}

    所以问题是:

    1. 为什么我会收到这个例外?
    2. 是否有另一种尝试完成此类任务的方式(有效)?请注意,我正在尝试使用“Except”方法。也许还有更好的方法。

1 个答案:

答案 0 :(得分:2)

这个怎么样:

var employeesNotAssignedToProject = db.Employees.Select(e => e).Where(e => (e.Projects.Count(c => c.ProjectID == 1)) == 0)

我没有对此进行过测试,但基本上它的作用是通过检查具有给定ID的项目数来仅选择那些项目集合中不包含相关项目的员工。