整合多个查询到一个与EF这样吗?(Aggregating multiple queries into

2019-09-16 08:14发布

我在我的应用程序中使用EF 4.0 POCO。 有什么缺点来获取这样的信息?

给定一个customerIdproductId ,我想申请,要求我从需要多个查询数据库获取大量的信息蝇头件的一些业务规则。 相反,我可以写一个查询,如下所示:

var customerId = 1;
var productId = 1;

var aggregateQuery = 
    from entry in Customers.Take(0).DefaultIfEmpty()
    select new
    {
        numberOfOrders = SalesOrderHeaders.Where (header => header.CustomerID == customerId).Count(),
        canSellProduct = Products.Where(product => product.ProductID == productId && product.SellEndDate > DateTime.Now).Count () > 0

        //more infromation of this sort, required to enforce business rules
    };

var informationPacket = aggregateQuery.First();

Customers.Take(0).DefaultIfEmpty()只是提供了一种方式来启动查询和CustomersSalesOrderHeadersProducts都是从上下文EF的ObjectQuery实例(这个例子如果从LinqPad)。 这将导致以下SQL:

-- Region Parameters
DECLARE @p0 Int = 1
DECLARE @p1 Int = 1
DECLARE @p2 DateTime = '2012-04-04 21:02:20.798'
DECLARE @p3 Int = 0
-- EndRegion
SELECT TOP (1) [t6].[value] AS [numberOfOrders], [t6].[value2] AS [canSellProduct]
FROM (
    SELECT (
        SELECT COUNT(*)
        FROM [Sales].[SalesOrderHeader] AS [t3]
        WHERE [t3].[CustomerID] = @p0
        ) AS [value], 
        (CASE 
            WHEN ((
                SELECT COUNT(*)
                FROM [Production].[Product] AS [t5]
                WHERE ([t5].[ProductID] = @p1) AND ([t5].[SellEndDate] > @p2)
                )) > @p3 THEN 1
            WHEN NOT (((
                SELECT COUNT(*)
                FROM [Production].[Product] AS [t5]
                WHERE ([t5].[ProductID] = @p1) AND ([t5].[SellEndDate] > @p2)
                )) > @p3) THEN 0
            ELSE NULL
         END) AS [value2]
    FROM (
        SELECT NULL AS [EMPTY]
        ) AS [t0]
    OUTER APPLY (
        SELECT TOP (0) NULL AS [EMPTY]
        FROM [Sales].[Customer] AS [t1]
        ) AS [t2]
    ) AS [t6]

Answer 1:

我瘦到使用单独的查询,原因有三:

  • 隔离 :单独的查询是更清晰,更好的维护:用一个整体的查询,每一个变化可能有许多副作用。 这是比较容易的业务规则适用于小型的,孤立的代码片段。
  • 效率 :你可能最终构成一个查询比单独的查询远远低于低效的,因为它变得不可能找到一个很好的执行计划,这可能甚至超过了多个数据库往返的成本(但是这是确定基准)。
  • 锁定的 :它可以工作了一段时间,直到需求的方式,一个大的查询不工作了改变:可能需要不相称的大量的重构。

再加上一点直觉:需要一些技巧( Take(0)是常反映不好的设计的(也许你只是他妈的辉煌,但在我的情况下,它通常是前者)。

不过,我看当然的潜在优势。 至于说,它可能会变成因为少分贝往返更好的表现。 并且它是相当舒适的使用一个select new组成一个数据传输对象,而不是从单独的位一起编织它。

所以,没有一个明确的判决。 我个人比较喜欢让事情变得简单和处理性能时,它确实是一个问题。



文章来源: Aggregating multiple queries into one with EF like this?