实体框架:在父表上额外调用数据库

时间:2014-05-01 14:21:50

标签: entity-framework profiler

我的模型很简单

public partial class Customer
{
    public Customer()
    {
        this.Orders = new HashSet<Order>();
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Order> Orders { get; set; }
}

public partial class Order
{
    public Order()
    {
        this.OrderDetails = new HashSet<OrderDetail>();
    }

    public int Id { get; set; }
    public string OrderDescription { get; set; }
    public int CustomerId { get; set; }

    public virtual Customer Customer { get; set; }
    public virtual ICollection<OrderDetail> OrderDetails { get; set; }
}

public partial class OrderDetail
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public string ProductName { get; set; }
}

此代码是使用EF的.edmx文件生成的。然后我从这个模型生成了我的数据库。我正在急切地加载以获取数据。

    public virtual IQueryable<T> GetAllEagerLoadSelective(string[] children)
    {
        foreach (var item in children)
        {
            DbSet.Include(item).Load();
        }
        return DbSet;
    } 

我的电话看起来像

        string[] Navs = { "OrderDetails" };
        var orders = VNUow.Order.GetAllEagerLoadSelective(Navs);
        var temp = orders.ToList();
        return temp;

LazyLoading设置为false

正在运行两个查询,第一个有意义

SELECT 
[Project1].[Id] AS [Id], 
[Project1].[OrderDescription] AS [OrderDescription], 
[Project1].[CustomerId] AS [CustomerId], 
[Project1].[C1] AS [C1], 
[Project1].[Id1] AS [Id1], 
[Project1].[OrderId] AS [OrderId], 
[Project1].[ProductName] AS [ProductName]
FROM ( SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[OrderDescription] AS [OrderDescription], 
    [Extent1].[CustomerId] AS [CustomerId], 
    [Extent2].[Id] AS [Id1], 
    [Extent2].[OrderId] AS [OrderId], 
    [Extent2].[ProductName] AS [ProductName], 
    CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
    FROM  [dbo].[Orders] AS [Extent1]
    LEFT OUTER JOIN [dbo].[OrderDetails] AS [Extent2] ON [Extent1].[Id] = [Extent2].[OrderId]
)  AS [Project1]
ORDER BY [Project1].[Id] ASC, [Project1].[C1] ASC

但为什么会出现第二个查询?在父表上选择...

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[OrderDescription] AS [OrderDescription], 
[Extent1].[CustomerId] AS [CustomerId]
FROM [dbo].[Orders] AS [Extent1]

1 个答案:

答案 0 :(得分:0)

您正在调用Load()来填充内部集,这是创建第一个查询的内容。然后你返回dbSet。然后你在DbSet上调用ToList(),这实际上是另一个查询。查询DbSet不会导致数据库查询的唯一情况是使用Find()函数检索已加载的实体。其他所有内容都是对db 的查询,即使它只返回已经加载的实体

要解决此问题,请更改GetAllEagerLoadSelective,如下所示:

public virtual IList<T> GetAllEagerLoadSelective(string[] children)
{
    IQueryable<T> dbSet = DbSet;
    foreach (var item in children)
    {
        dbSet = dbSet.Include(item);
    }
    return dbSet.ToList();
}