1

次のEFコードがあるとしましょう。

context.Employees.Select(e => e
{
    FullName = e.FirstName + " " + e.LastName,
    StartDate = e.StartDate,
    ... // Grab other data
};

今、私は複数の場所でフルネームを作成していることに気付いたかもしれませんが、一元化したいと思っています。これをリファクタリングすることは可能ですか?

メソッドまたはFuncにすると、SQLに変換できないため、EFエラーが発生します。

注:これは単純な例です。割り当ての「選択」、「場所」などではるかに複雑になる可能性があるため、ToListを追加してから追加のコードを実行することは最適ではなく、の定義に適合しません。機能を変更する必要があり、保守性を高めるだけではないため、リファクタリング。

4

2 に答える 2

0

1つの解決策は、 LinqKitAsExpandableのメソッドを使用することです。

Expression<Func<Employee,string>> fullName = e => e.FirstName + " " + e.LastName;
context.Employees.AsExpandable().Select(e => e
{
    FullName = fullName.Compile().Invoke(e),
    StartDate = e.StartDate,
    ... // Grab other data
};

リンクされた記事から:

コンパイルは、Expressionクラスに組み込まれているメソッドです。これは、式をコンパイラーを満足させるプレーンなFuncに変換します。もちろん、このメソッドが実際に実行された場合、式ツリーではなくコンパイルされたILコードになり、LINQtoSQLまたはEntityFrameworkは例外をスローします。しかし、ここに賢い部分があります。コンパイルが実際に実行されることはありません。また、LINQtoSQLまたはEntityFrameworkがそれを確認することもありません。コンパイルの呼び出しは、AsExpandableを呼び出すことによって作成され、正しい式ツリーの代わりに使用される特別なラッパーによって完全に削除されます。

または、EntityFrameworkを使用してモデル定義関数を作成することを検討することもできます。Employeeクラス自体にFullNameプロパティを定義する場合は、 Microsoft.Linq.Translationsライブラリもあります。

于 2012-11-14T23:32:12.020 に答える
0

エンティティクラス自体でそれを行うためのより良い集中化された方法だと思います。NotMapped必要なフォーマットされたデータを返すためにデータベースにあるはずのエンティティクラスにReadOnlyプロパティを追加できます。

Public class Employee
{
//...

public string fullName{get { return  FirstName + " " + LastName;}}
}
于 2012-11-15T03:36:27.640 に答える