c# - 如何使用 3 includes 优化 Entity Framework 查询

标签 c# entity-framework

我在 .Net 4 上使用 EF 5

我有以下模型:

public class Order
{

    [Key]
    public int Id { get; set; }
    public string OrderId { get; set; }

    public Address BillingAddress { get; set; }
    public Address DeliveryAddress { get; set; }
    public ICollection<OrderLine> OrderLines { get; set; }
}

public class OrderLine
{
    [Key]
    public int Id { get; set; }

    public string Description { get; set; }
    public decimal UnitPrice { get; set; }
    public int Quantity { get; set; }
    public string SKU { get; set; }
    public decimal ShippingCost { get; set; }
    public decimal Tax { get; set; }
}

public class Address
{
    [Key]
    public int Id { get; set; }
    public string Addressee { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string AddressLine3 { get; set; }
    public string Town { get; set; }
    public string County { get; set; }
    public string Country { get; set; }
    public string Postcode { get; set; }
}

和模型配置:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Order>().HasMany(x => x.OrderLines).WithRequired().WillCascadeOnDelete();
    modelBuilder.Entity<Order>().HasOptional(x => x.BillingAddress).WithOptionalDependent().WillCascadeOnDelete();
    modelBuilder.Entity<Order>().HasOptional(x => x.DeliveryAddress).WithOptionalDependent().WillCascadeOnDelete();

    base.OnModelCreating(modelBuilder);
}

当我运行以下查询时,我得到带有 19 个连接 的 sql,这对于简单的关系来说似乎过多了

context.Orders
       .Where(x => x.OrderId == orderId)
       .Include(x => x.OrderLines)
       .Include(x => x.BillingAddress)
       .Include(x => x.DeliveryAddress)
       .FirstOrDefault();

我做错了什么吗?是否有不同的格式来优化生成的 SQL 的 linq 查询?

编辑:

这是实际查询:https://gist.github.com/4278014

最佳答案

我认为问题出在帐单地址和送货地址上的 WithOptionalDependent 上。这在地址和订单之间创建了 1:1 的关系,即使表是为 1:many 关系设置的。

如果您更改配置以改为使用 WithMany:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Order>().HasMany(x => x.OrderLines).WithRequired().WillCascadeOnDelete();
    modelBuilder.Entity<Order>().HasOptional(x => x.BillingAddress).WithMany().WillCascadeOnDelete();
    modelBuilder.Entity<Order>().HasOptional(x => x.DeliveryAddress).WithMany().WillCascadeOnDelete();

    base.OnModelCreating(modelBuilder);
}

查询要简单得多,本质上等同于:

...
FROM [Orders]
LEFT OUTER JOIN [Addresses] As B ON [Orders].[BillingAddress_Id] = B.[Id]
LEFT OUTER JOIN [Addresses] As D ON [Orders].[DeliveryAddress_Id] = D.[Id]
LEFT OUTER JOIN [OrderLines] ON [Orders].[Id] = [OrderLines].[Order_Id]

关于c# - 如何使用 3 includes 优化 Entity Framework 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13864675/

相关文章:

c# - 使用 AzukeKeyVault key 签署 JWT

c# - 在列表中查找一个属性包含重复值的对象

entity-framework - ADO.NET 实体 : getting data from 3 tables

c# - 编写此 linq 查询的更好方法是什么?

c# - 如何使用 viewmodel 从 linq 查询返回列表

c# - 如果在 LINQ 中找到,如何在最后一条记录上应用包含并删除?

c# - 正则表达式。驼峰式下划线。忽略第一次出现

c# - MVC - 将发布数据插入数据库

c# - 内容类型 text/xml;响应消息的字符集 ="utf-8"与绑定(bind)的内容类型不匹配(文本/xml;字符集=utf-8)

c# - 用C#在图片上写文字