我的模型很简单
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]
答案 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();
}