【问题标题】:Get related entity id without loading it获取相关实体ID而不加载它
【发布时间】:2012-12-25 02:56:10
【问题描述】:

我需要使用实体框架(代码优先)列出所有订单及其对应的客户 ID。这应该可以在不查询客户表的情况下实现,因为客户 ID 是 Orders 表中的 FK。但是,EF 也会针对 Orders 和 Customers 表生成选择。

这是实体模型和用于查询订单的代码:

public class Order
{
    public virtual Guid Id { get; set; }

    public virtual string Description { get; set; }

    public virtual Customer Customer { get; set; }
}

public class Customer
{
    public virtual Guid Id { get; set; }

    public virtual string Name { get; set; }
}

using (var context = new LazyLoadingEfContext())
{
    foreach (var order in context.Orders)
    {
        Console.WriteLine("Order {0}, Customer {1}", order.Description, order.Customer.Id);
    }
}

生成的SQL如下:

SELECT 
1 AS [C1], 
[Extent1].[Id] AS [Id], 
[Extent1].[Description] AS [Description], 
[Extent1].[Customer_Id] AS [Customer_Id]
FROM [dbo].[Orders] AS [Extent1]

exec sp_executesql N'SELECT 
[Extent2].[Id] AS [Id], 
[Extent2].[Name] AS [Name]
FROM  [dbo].[Orders] AS [Extent1]
INNER JOIN [dbo].[Customers] AS [Extent2] ON [Extent1].[Customer_Id] = [Extent2].[Id]
WHERE ([Extent1].[Customer_Id] IS NOT NULL) AND ([Extent1].[Id] =     
@EntityKeyValue1)',N'@EntityKeyValue1 uniqueidentifier',
@EntityKeyValue1='FF947EF3-5A3F-4A26-BDB9-039C49F559A7'

(加上参数@EntityKeyValue1具有不同值的其他相同查询)

有没有办法配置 EF 以便从“父”对象检索相关实体 ID 而不是加载相关实体?

顺便说一句,我已经使用 NHibernate 测试了相同的场景,并且只对 Orders 表执行了一个查询:

SELECT this_.Id as Id1_0_, this_.Description as Descript2_1_0_, 
this_.Customer_id as Customer3_1_0_ FROM [Order] this_

【问题讨论】:

  • 为什么要在 Order 中的每个属性之前放置 virtual?
  • 尝试为正确的字段注释属性外键...
  • @BhushanFirake virtual 应该只在 Customer 属性上(对此感到抱歉)。

标签: entity-framework ef-code-first


【解决方案1】:

试试这个:

public class Order
{
    public virtual Guid Id { get; set; }

    public virtual string Description { get; set; }

    public Guid CustomerID { get; set; }

    [ForeignKey("CustomerID ")]
    public virtual Customer Customer { get; set; }
}

之后,您应该能够在 foreach 循环中只获得 order.CustomerID,而无需查询客户表。

【讨论】:

  • 感谢您的回答,但是我希望我的域模型尽可能干净,添加 CustomerID 属性将起作用(实际上这是我为避免性能问题所做的)但我想知道是否有办法避免在没有该解决方法的情况下加载完整实体。
  • 我几乎可以肯定没有。调用 order.Customer.*(其中 * 是任何客户属性)将始终导致对数据库的查询。
  • @MarcinJuraszek:看起来像。使用int Ids,我看到EF 从关联中推断出相关实体的主键值(不查询其他实体)。有了向导,这似乎有所不同。 @jrowies:暴露原始外键可能感觉像是在污染模型,但在 EF 中通常建议这样做(参见例如 Lerman 和 Miller 的书 DbContext)。
  • 感谢你们的帮助,我想我会保留 FK 属性。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-23
  • 1970-01-01
  • 2020-02-14
相关资源
最近更新 更多