3

我在我的应用程序中使用 EF 4.0 POCO。检索这样的信息有什么缺点吗?

给定 acustomerId和 a productId,我想应用一些业务规则,这些规则要求我从需要多个查询的数据库中获取大量信息。相反,我可以像这样编写一个查询:

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()只是提供了一种启动查询的方法,Customers并且SalesOrderHeadersProducts是上下文中的 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]
4

1 回答 1

1

我倾向于使用单独的查询,原因有以下三个:

  • 隔离:单独的查询更清晰,更易于维护:使用一个整体查询,每次更改都可能有许多副作用。将业务规则应用于小的、孤立的代码段更容易。
  • 效率:您最终可能会编写一个比单独查询效率低得多的查询,因为不可能找到一个好的执行计划,这甚至可能超过更多数据库往返的成本(但这要进行基准测试)。
  • 锁定:它可能会工作一段时间,直到需求以一种大查询不再工作的方式发生变化:可能需要不成比例的大量重构。

再加上一点直觉:需要一些技巧 ( Take(0)) 通常表示糟糕的设计(或者也许你只是 f** 聪明,但在我的情况下通常是前者)。

但是,我当然看到了潜在的优势。如前所述,由于较少的数据库往返,它可能会表现得更好。select new使用一个来组合一个数据传输对象而不是从单独的位将它编织在一起是相当舒服的。

所以,没有一个明确的判决。就我个人而言,我喜欢让事情变得简单,并在真正成为问题时处理性能。

于 2012-04-06T20:20:54.960 回答