4

次のコードがあるとします。

public class Dto
{
  public int Id;
  public string Name;
}    

...

using (var db = new NorthwindDataContext())
{
  var q = from boss in db.Employees
          from grunt in db.Employees.Where(p => p.ReportsTo == boss.EmployeeID).DefaultIfEmpty()
          select new Dto { Id = boss.EmployeeID, Name = grunt.FirstName };
}

セレクターを式として抽出して別の場所に保存したい。メソッド構文では、次のようになります。

Expression<Func<Employee, Employee, Dto>> selector = (boss, grunt) => new Dto
{
  Id = boss.EmployeeID, Name = grunt.FirstName
};

using (var db = new NorthwindDataContext())
{
  var q = db.Employees.SelectMany(boss => db.Employees.Where(p => p.ReportsTo == boss.EmployeeID).DefaultIfEmpty(), selector);
}

このLinqToSqlメソッドチェーンを、式変数を所定の位置に保持したままクエリ構文に変換することは可能ですか?

UPD:

私の質問を明確にするために、左結合にDefaultIfEmptyを使用しています。これは、等しいクエリの短い形式です。

using (var db = new NorthwindDataContext())
{
  var q = from boss in db.Employees
          join stub in db.Employees on boss.EmployeeID equals stub.ReportsTo into stubi
          from grunt in stubi.DefaultIfEmpty()
          select new Dto { Id = boss.EmployeeID, Name = grunt.FirstName };
}

インライン式を使用してコンパイルされるため、これは正常に機能します。null対応するがない場合は、[名前]フィールドに割り当てgruntます。ただし、このクエリを外部マッパーメソッドの呼び出しで書き直すと、メソッド呼び出しにコンパイルされます。これにより、null許容gruntの引数が取得され、NullReferenceExceptionが発生します。

public static Dto GetDto(Employee boss, Employee grunt)
{
  return new Dto
    {
      Id = boss.EmployeeID,
      Name = grunt.FirstName
    };
}

using (var db = new NorthwindDataContext())
{
  var q = from boss in db.Employees
          join stub in db.Employees on boss.EmployeeID equals stub.ReportsTo into stubi
          from grunt in stubi.DefaultIfEmpty()
          select GetDto(boss, grunt);
}

もちろん、マッパーメソッドにヌルチェックを追加することはできますが、DALで達成しようとしているのは、セレクターをマッパークラスに抽出し、そこでヌルチェックを省略することです。

4

2 に答える 2

0

クエリ構文を常に使用できるとは限りません。メソッドチェーンでのみ計算を表現できる場合があります。この特定のケースでは、述語がインラインの場合、クエリ構文は舞台裏でラムダを導入しますが、それを変数に入れているため、ラムダの場合のように、その変数の使用方法を指定する方法はありません。クエリ構文による。

于 2012-10-23T10:23:42.923 に答える
0

が必要な理由がわかりませんExpression- を使用してFuncください。これはうまくいくはずです:

Func<Employee, Employee, Dto> selector = (boss, grunt) => new Dto 
{ 
Id = boss.EmployeeID, Name = grunt.FirstName 
}; 

using (var db = new NorthwindDataContext()) 
{ 
var q = from boss in db.Employees 
        from grunt in db.Employees.Where(p => p.ReportsTo == boss.EmployeeID).DefaultIfEmpty() 
        select selector(boss, grunt)
} 
于 2012-10-23T09:22:53.937 に答える