2

次のように作成する従業員のリストがあります。

var employees = db.employees.Where(e => e.isActive == true).ToList();

var latestSales = from es in db.employee_sales.Where(x => x.returned == false);

今私が欲しいのは、次のような結果です:

int employeeId
List<DateTime> lastSaleDates

だから私はこれを試しましたが、クエリが完了するまでに非常に長い時間がかかります:

var result = 
  (from e in employees
   select new EmployeeDetails
   {
      EmployeeId = e.employeeId,
      LastSaleDates = 
           (from lsd in latestSales.Where(x => x.EmployeeId == e.EmployeeId)
                                   .Select(x => x.SaleDate)
            select lsd).ToList()
   };

上記は機能しますが、完了するまでに文字通り 1 分かかります。

これを行うためのより効率的な方法は何ですか?

4

3 に答える 3

6

結合を使用して、単一のクエリですべてのデータを取得できます

var result = from e in db.employees.Where(x => x.isActive)
             join es in db.employee_sales.Where(x => x.returned)
                  on e.EmployeeId equals es.EmployeeId into g
             select new {
                  EmployeeId = e.employeeId,
                  LastSaleDates = g.Select(x => x.SaleDate)
             };

ToList()残念ながら、Linq to Entities でメソッドを使用することはできません。したがって、匿名オブジェクトを手動でマップするか、タイプを にEmployeeDetails変更してください。LastSalesDatesIEnumerable<DateTime>

于 2013-06-12T20:28:32.203 に答える
3

への呼び出しは、ToList物事をメモリに引き込みます。クエリ全体をメモリに取り込むのではなく、Linq 式を構築することを選択する必要があります。2 番目のクエリでは、(EF ではなく) Linq-to-objects ドメインで操作しているため、各従業員に対して新しいクエリを発行しています。への呼び出しを削除してみてくださいToList

また、このクエリをより良くするために、外部キー関連付けプロパティを使用することも検討する必要があります。関連プロパティは、EF の最も強力で便利な部分の一部です。詳細については、こちらをご覧ください。適切な関連付けプロパティがある場合、クエリは次のようになります。

var result = from e in employees
      select new EmployeeDetails
    {
        EmployeeId = e.employeeId,
        LastSaleDates = e.AssociatedSales
    }

代わりに結合の使用を検討することもできます。Linq のJoin方法については、こちらを参照してください。

于 2013-06-12T20:28:39.923 に答える
1

モデルで従業員と latestSales の間に関連付けはありますか? SQL プロファイラーまたはその他のプロファイリング ツールをチェックして、生成された SQL を確認しましたか? ToList() が従業員ごとに個別のクエリを発行していないことを確認してください。

として結果構造を使用できる場合はIEnumerable<EmployeeId, IEnumerable<DateTime>>、これを次のように変更することを検討できます。

var result = (from e in employees
        select new EmployeeDetails
        {
                EmployeeId = e.employeeId,
                LastSaleDates = (from lsd in latestSales
                                 where e.employeeId equals lsd.EmployeeId
                                 select lsd.SaleDate)
        };

http://www.thinqlinq.com/Post.aspx/Title/LINQ-to-Database-Performance-hintsに、問題を追跡するための一般的な推奨事項がいくつかあります。

于 2013-06-12T20:33:51.233 に答える