实体框架QueryBuilder和实体集合迭代

时间:2014-08-12 14:54:20

标签: entity-framework

我正在尝试使用带有实体框架的QueryBuilder创建以下查询,而不必遍历SupplierBand实体集合。

SELECT ClientSupplier.SupplierId, SupplierBand.BandId
FROM ClientSupplier
INNER JOIN Supplier ON Supplier.SupplierID = ClientSupplier.SupplierID
INNER JOIN SupplierBand On SupplierBand.SupplierID = Supplier.SupplierID 
WHERE ClientSupplier.ClientID = @ClientID

供应商拥有ClientSupplier的1对多, 供应商与SupplierBand有1对多

以下成功运行(为简单起见省略了条款)

var clientPreferredSupplierQuery = DataContextFactory.GetDataContext().ClientSuppliers.Include("Suppliers").Select("it.ClientSupplier.SupplierId", "it.Supplier.SupplierBands");

为了获得SupplierBand.BandId,我必须使用DbDataRecord上的foreach在代码中迭代SupplierBands实体集合。我担心与上面运行本机sql相比,这次迭代会很慢。

数据库是遗留的,无法更改,我希望继续将Entity Sql与Query Builder一起使用。

使用QueryBuilder有更好的方法吗? Idealy我想让Entity Framework运行一个查询来实现这一点。

提前致谢。

DT

1 个答案:

答案 0 :(得分:1)

您提到您担心EF生成的查询的性能低于SQL查询,但听起来您还没有测量过它。在你开始研究如何优化它之前,我会发现它是否需要它;如果性能变得非常相似,那么你就不必浪费时间去尝试微观优化它!

首先看一下EF生成的SQL查询。您可以使用EF 6日志记录功能(http://msdn.microsoft.com/en-us/data/dn469464.aspx),使用EF分析器(如Hibernating Rhino的EFProf)等。查看EF生成的内容:它是否与您所使用的查询相同写?它是否执行多次数据库调用?

如果它是相同的,则无需进一步研究它。如果不是,那么你应该衡量两种选择的表现(我猜你关心这里的速度:))。然后尝试确定问题所在,以及是否可以从EF方面解决。这一切都取决于您的要求和优先级,但至少在衡量之后,您将能够根据数据做出决定。

我意识到这是一个更全球化的回复,而不是针对您的具体情况,但希望它会对您有所帮助。

在测量结果后编辑了更多详细信息

从您的评论中看起来您对SupplierBands的查询存在N + 1问题。供应商正在急切地加载(包括Include),但不是SupplierBands,这是导致所有数据库调用的原因。

但是,我在您的SQL查询中看到您只关心SupplierId和BandId。这可能是您示例的简化,但如果不是,您可以使用以下内容优化查询:

ClientSuppliers.Include(x => x.Supplier.Select(s => s.SupplierBands))
               .Select(x => new { x.SupplierId, x.Supplier.SupplierBands.Select(b => b.BandId)};

将使用映射实体加载ID,因此您无需急于加载实体本身即可获取它们。如果您需要完整的相关对象,那将是一个不同的故事。