0

簡略化された例:FirstNameLastNameという表があります。私は、長さでソートされた完全な敬礼がNではないすべての人々を検索することに興味があります。それを達成するために、私はこのようなコードを持っている:Entity Frameworkで投影法を選択してフィルタを適用します。

var result = await Context.People 
       .Select(p => new PersonWithSalutation 
       { 
        FirstName = p.FirstName, 
        LastName = p.FirstName, 
        FullSalutation = p.FirstName + " " + p.LastName 
       }) 
       .Where(p => p.FullSalutation.Length < maxLength) 
       .OrderBy(p => p.FullSalutation) 
       .Take(maxResults) 
       .ToListAsync(); 

クエリは次のようになります。

SELECT TOP (10) 
    [Project1].[C1] AS [C1], 
    [Project1].[Name] AS [Name], 
    [Project1].[Id] AS [Id], 
    [Project1].[C2] AS [C2] 
    FROM (SELECT 
     [Extent1].[Id] AS [Id], 
     [Extent1].[Name] AS [Name], 
     1 AS [C1], 
     ...calculated stuff... AS [C2] 
     FROM [dbo].[People] AS [Extent1] 
     WHERE ...exactly the same stuff... <= @p__linq__3 
    ) AS [Project1] 
    ORDER BY [Project1].[C2] ASC 

これは、トリックを行い、データベースへの単一のクエリを生成します。問題は、結果のクエリで2回現れるため、計算された投影です:SELECTに1回、次にWHEREに1回です。この例は単純化されていますが、私の実際のケースでは、重度の数学演算を行っています。これは1回だけ計算したいと考えています。上記のように、C2はorder句で再利用されます。私はWHERE節と同じことをしたいと思いますが、これはさらに別のサブクエリを含むと思われます)。どうすればこれを達成できますか?

+0

私は計算が同じであることを実現するために、SQL Serverを仮定してないだろうこの場合は2回です。あなたはそれが信じる理由がありますか? – John

答えて

1

クエリーのビルディングは予測不可能なプロセスなので、希望のlinqを検索することで多くの時間を費やすことができます。それで、私は別のアプローチを提供しています。 POCOクラスにFullSalutationプロパティを追加し、FirstNameまたはLastNameが変更された場合は、DBを使用して計算されます(Computed)。この場合、実際にはが必要な場合は、が必要なときに計算が実行されます。

public class POCO 
{ 
    public int ID { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
    public string FullSalutation { get; private set; } 
} 

次に新しい移行を追加します。

public override void Up() 
{ 
    //AddColumn("dbo.People", "FullSalutation", x => x.String()); 
    Sql("ALTER TABLE dbo.People ADD FullSalutation AS FirstName + ' ' + LastName"); 
} 
public override void Down() 
{ 
    DropColumn("dbo.People", "FullSalutation"); 
} 

最後に、あなたのクエリは次のようになります。

var result = await Context.People 
      .Where(p => p.FullSalutation.Length < maxLength) 
      .Select(p => new PersonWithSalutation 
      { 
        FirstName = p.FirstName, 
        LastName = p.LastName, 
        FullSalutation = p.FullSalutation 
      }).OrderBy(p => p.FullSalutation).Take(maxResults).ToListAsync(); 
関連する問題