3

アプリケーションで EF 4.0 POCO を使用しています。このような情報を取得することの欠点はありますか?

customerIdaと aが与えられた場合、productId複数のクエリを必要とするデータベースから多くの小さな情報を取得する必要があるいくつかのビジネス ルールを適用したいと思います。代わりに、次のように 1 つのクエリを記述できます。

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コンテキストからの EF ObjectQuery インスタンスです (この例は LinqPad からの場合)。これにより、次の SQL が生成されます。SalesOrderHeadersProducts

-- 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

私は3つの理由で別々のクエリを使用することに傾倒しています:

  • 分離:個別のクエリははるかに明確で保守性が高くなります。1つのモノリスクエリでは、変更ごとに多くの副作用が発生する可能性があります。小さくて孤立したコードにビジネスルールを適用する方が簡単です。
  • 効率:適切な実行プランを見つけること不可能になるため、個別のクエリよりもはるかに非効率なクエリを作成することになります。これは、より多くのデータベースラウンドトリップのコストを上回る可能性があります(ただし、ベンチマークする必要があります)。
  • ロックイン:1つの大きなクエリが機能しなくなるように要件が変更されるまで、しばらくは機能する可能性があります。不釣り合いな量のリファクタリングが必要になる場合があります。

それに加えて、ちょっとした直感があります。トリック(Take(0))が必要な場合は、デザインが悪いことを示していることがよくあります(または、あなたは素晴らしいですが、私の場合は通常前者です)。

ただし、もちろん潜在的な利点もあります。前述のように、dbラウンドトリップが少ないため、パフォーマンスが向上する可能性があります。select newまた、個別のビットからまとめて編成するのではなく、1つを使用して1つのデータ転送オブジェクトを作成するのは非常に快適です。

したがって、明確な評決ではありません。個人的には、物事をシンプルに保ち、本当に問題になるときにパフォーマンスに対処するのが好きです。

于 2012-04-06T20:20:54.960 に答える