2016-06-29 14 views
0

私は単純なlinqクエリを持っています。これは結果をcreteriaでソートします。エンティティフレームワーククエリを簡略化

var vehicles = context.Vehicles 
    .AsNoTracking() 
    .Where(v => v.CreatedAt >= DbFunctions.AddDays(DateTime.UtcNow, -10)) 
    .ToList(); 

しかし、エンティティフレームワークは

SELECT 
CASE WHEN ((NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND (NOT (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL))) AND (NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN '0X' WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)) THEN '0X0X' WHEN (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL)) THEN '0X1X' ELSE '0X2X' END AS [C1], 
[Extent1].[Id] AS [Id], 
[Extent1].[CreatedAt] AS [CreatedAt], 
[Extent1].[Name] AS [Name], 
CASE WHEN ((NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND (NOT (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL))) AND (NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS bit) WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)) THEN [Project1].[HasCycleCar] WHEN (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL)) THEN CAST(NULL AS bit) END AS [C2], 
CASE WHEN ((NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND (NOT (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL))) AND (NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS int) WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)) THEN CAST(NULL AS int) WHEN (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL)) THEN [Project3].[Seats] END AS [C3], 
CASE WHEN ((NOT (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL))) AND (NOT (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL))) AND (NOT (([Project2].[C1] = 1) AND ([Project2].[C1] IS NOT NULL)))) THEN CAST(NULL AS int) WHEN (([Project1].[C1] = 1) AND ([Project1].[C1] IS NOT NULL)) THEN CAST(NULL AS int) WHEN (([Project3].[C1] = 1) AND ([Project3].[C1] IS NOT NULL)) THEN CAST(NULL AS int) ELSE [Project2].[Capacity] END AS [C4] 
FROM [dbo].[Vehicles] AS [Extent1] 
LEFT OUTER JOIN (SELECT 
    [Extent2].[Id] AS [Id], 
    [Extent2].[HasCycleCar] AS [HasCycleCar], 
    cast(1 as bit) AS [C1] 
    FROM [dbo].[Motorcycles] AS [Extent2]) AS [Project1] ON [Extent1].[Id] = [Project1].[Id] 
LEFT OUTER JOIN (SELECT 
    [Extent3].[Id] AS [Id], 
    [Extent3].[Capacity] AS [Capacity], 
    cast(1 as bit) AS [C1] 
    FROM [dbo].[Trucks] AS [Extent3]) AS [Project2] ON [Extent1].[Id] = [Project2].[Id] 
LEFT OUTER JOIN (SELECT 
    [Extent4].[Id] AS [Id], 
    [Extent4].[Seats] AS [Seats], 
    cast(1 as bit) AS [C1] 
    FROM [dbo].[PassengerCars] AS [Extent4]) AS [Project3] ON [Extent1].[Id] = [Project3].[Id] 
WHERE [Extent1].[CreatedAt] >= (DATEADD (day, -10, SysUtcDateTime())) 

に、この単純なクエリを変換するには、より面倒なクエリであること、私は基本情報が必要ですが、EFは、すべての読み込みが付属しています。私はEFが多態的な振る舞いを遵守し、それが作成された型のオブジェクトを返す必要があることを理解しています。

しかし、私は彼が非間違いを読んでいないと私は簡単に思い浮かべることができますか?

+0

あなたはビークルレコードのリストを取得していますか?もしそうなら、その問題は何ですか?これは、あなたが書いたコードがやるべきことではありませんか?あなたが最後に貼り付けたものは、単にEFのsqlへの変換であるため、C#linqの構文をデータベースが読めるsqlに変換することができます(RDBMSはC#のlinqの解釈方法を知らない) – Veverke

+0

ええ、各車両のために –

+0

「全部」とはどういう意味ですか?結合はおそらく、Vechileクラス(およびそのネストされたクラス)で定義した仮想コレクションを変換します。どのようにそれが期待されますか? – Veverke

答えて

1

あなたが唯一のエンティティタイプのプロパティのサブセットをしたい場合は、(どちらか匿名または名前付きの型に)クエリでの投影を含めることができます。

resultsが列挙されて
var results = from v in context.Vehicles 
       … 
       select new VechicleSubSet { 
       Id = v.Id, 
       Name = v.Name 
       }; 

(クエリをトリガNameIdのみが選択されます(クエリの別の場所で使用されている場合は、他の列が参照される可能性があります)。

注:あなたのSQLでは、オブジェクトテーブルマッピングでTable per Classのように設定されているように見えます。したがって、EFは単一のテーブルだけでなく、そのマッピング内のすべてのデータを返そうとしています。

+0

それは本当のようですが、私はパフォーマンスをチェックして答えを受け取ります。ありがとう。 –