使用外键属性或导航属性查询? EF 4.1

时间:2011-07-02 22:14:25

标签: c# query-optimization entity-framework-4.1

我正在将一些POCO类映射到具有多个查找表的现有数据库,我想知道最有效或推荐的方法是什么。

假设有一个映射到Employee表的Employee模型类:

public class Employee
{
    public int ID { get; set }
    public string Name { get; set }

    [ForeignKey("Role")]
    public int RoleID { get; set }
    public virtual EmployeeRole Role { get; set }
}

EmployeeRole类/表看起来像:

public class EmployeeRole
{
    public int ID { get; set } // For instance: 1
    public string Description { get; set } // for instance: Manager
}

我知道我不需要明确声明外键RoleID,但实际上我必须执行大量依赖于具有Employee的{​​{1}}的{​​{1}}的查询。 “管理器”。

现在的问题是,在结合效率,代码可读性和“数据独立性”方面哪些更好? 假设EmployeeRole是从存储库中提取的employees

  1. IQueryable
  2. employees.Where(e => e.RoleID == 1);
  3. employees.Where(e => e.EmployeeRole.ID == 1);
  4. 2和3的缺点是必须延迟加载导航属性,但是1的缺点是employees.Where(e => e.EmployeeRole.Description == "Manager");没有意义并且绑定到数据库的当前状态。

    我该怎么办?有选项4吗?

2 个答案:

答案 0 :(得分:4)

我的猜测是,所有3个查询都会产生类似的结果。至少1和2应该生成相同的SQL。您可以通过在ObjectSet实例上调用“ToTraceString”来查看生成的SQL语句(我必须查看它,可能会隐藏在其他地方)。

- 编辑 我重新创建了您的模型,发现使用了以下查询(SQL Server)。您必须将查询强制转换为System.Data.Objects.ObjectQuery,它提供ToTraceString()方法。

employees.Where(e => e.RoleID == 1);
employees.Where(e => e.EmployeeRole.ID == 1);

// Both result in:
SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[RoleId] AS [RoleId]
FROM [dbo].[Employees] AS [Extent1]
WHERE 1 = [Extent1].[RoleId]

employees.Where(e => e.EmployeeRole.Description == "Manager");

SELECT  [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[RoleId] AS [RoleId]
FROM  [dbo].[Employees] AS [Extent1]
INNER JOIN [dbo].[Roles] AS [Extent2] ON [Extent1].[RoleId] = [Extent2].[Id]
WHERE N'Manager' = [Extent2].[Name]

答案 1 :(得分:0)

有点晚了,但我在表格中引入了“旗帜”的概念并取得了巨大的成功。例如,如果您知道经常查询管理器的内容,请在表中添加一个名称 “经理”,在您的代码中只需执行e.EmployeeRole.Manager即可。强类型,具有真正的商业意义。