我在我的应用程序中使用EF 4.0 POCO。 检索此类信息有什么缺点吗?
鉴于customerId
和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
,SalesOrderHeaders
和Products
是来自上下文的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]
答案 0 :(得分:1)
我倾向于使用单独的查询有三个原因:
再加上一点直觉:需要一些技巧(Take(0)
)往往表明设计不好(或者你可能只是f **辉煌,但在我的情况下,它通常是前者)。
但是,我看到了当然的潜在优势。如上所述,由于db往返次数较少,可能会表现得更好。使用一个select new
组成一个数据传输对象,而不是从单独的位编织它们,这是非常舒服的。
所以,不是一个明确的裁决。就个人而言,我喜欢保持简单,并在出现问题时处理性能。