1

少し問題があり、ケーキを食べて食べる方法はないかと思っていました。

現在、Linq2Sqlの使用方法について、リポジトリとクエリのスタイルパターンがありますが、問題が1つあり、それを解決するための適切な方法がわかりません。問題の例を次に示します。

var someDataMapper = new SomeDataMapper();
var someDataQuery = new GetSomeDataQuery();
var results = SomeRepository.HybridQuery(someDataQuery)
                            .Where(x => x.SomeColumn == 1 || x.SomeColumn == 2)
                            .OrderByDescending(x => x.SomeOtherColumn)
                            .Select(x => someDataMapper.Map(x));

return results.Where(x => x.SomeMappedColumn == "SomeType");

ここで注意を払うべき主なビットは、マッパー、クエリ、リポジトリ、そして最後のwhere句です。私はこれをより大きなリファクタリングの一部として行っていますが、わずかに異なる結果セットを取得しているが、ドメイン固有のモデルに同じ方法でマッピングしている同様のクエリがたくさんあることがわかりました。たとえば、を取り戻し、tbl_carそれをCarオブジェクトにマッピングします。したがって、マッパーは基本的に1つのタイプを取り、別のタイプを吐き出します。これは、selectで通常発生することとまったく同じです。

// Non mapped version
select(x => new Car 
{
    Id = x.Id,
    Name = x.Name,
    Owner = x.FirstName + x.Surname
});

// Mapped version
select(x => carMapper.Map(x));

したがって、カーマッパーは、同じ最終結果を返すが、途中で異なるビットを実行する同様のクエリを実行するすべての領域でより再利用可能です。ただし、MapをSQLに変換できないというエラーが表示され続けます。これは、望まないので問題ありませんが、式ツリーにあるため、変換しようとすることは理解しています。

{"Method 'SomeData Map(SomeTable)' has no supported translation to SQL."}

最後に、返され、マップされたオブジェクトは、他のオブジェクトが使用できるようにスタックのさらに上に渡されます。これは、Linq to SQLの合成機能を利用して、クエリに追加の条件を追加し、最後にToList()を使用するか、返されたデータを反復処理します。前の質問で答えたように、元のテーブルモデルではなく、マップされたモデルに基づいてフィルタリングします。これは完全に問題ないと思います。

データを取得するLinq2Sqlポイント

要約すると、その単一の部分をSQLに変換しようとせずに、示されているマッピングパターンを使用できますか?

4

1 に答える 1

5

はい、できます。AsEnumerable()最後の前に置くSelect

var results = SomeRepository.HybridQuery(someDataQuery)
                            .Where(x => x.SomeColumn == 1 || x.SomeColumn == 2)
                            .OrderByDescending(x => x.SomeOtherColumn)
                            .AsEnumerable()
                            .Select(x => someDataMapper.Map(x));

ただし、2番目Where(動作するもの)SomeMappedColumnはデータベースではなくメモリ内で実行されることに注意してください。この最後のwhere句が結果セットを大幅に減らす場合、これは問題になる可能性があります。


別のアプローチは、そのマッピングの式ツリーを返すメソッドを作成することです。マッピングで発生するすべてがSQLに変換可能である限り、次のようなものが機能するはずです。

Expression<Func<EntityType, Car>> GetCarMappingExpression()
{
    return new Expression<Func<EntityType, Car>>(x => new Car 
    {
        Id = x.Id,
        Name = x.Name,
        Owner = x.FirstName + x.Surname
    });
}

使用法は次のようになります。

var results = SomeRepository.HybridQuery(someDataQuery)
                            .Where(x => x.SomeColumn == 1 || x.SomeColumn == 2)
                            .OrderByDescending(x => x.SomeOtherColumn)
                            .Select(GetCarMappingExpression());
于 2013-01-16T10:13:25.230 に答える