2016-09-20 9 views
2

拡張メソッドを使用して、自分のエンティティモデルからビューモデルに投影するのが好きです。これは、私のモデルのためのフェッチを上/下では意味しませんし、コードを素敵で読みやすいものにしています。予測にはネストされたモデルが含まれることがあり、それらのサブ予測を再利用したいと考えています。拡張メソッドを使用したEF内の単一エンティティの投影

は、私は次のような何かをできるようにしたい:実際の投影

ため

ctx.People.FiltersAndThings().ToViewModels();//the project my DB Models into view models 

拡張メソッド

public static IQueryable<PersonModel> ToViewModels(this IQueryable<Person> entities) 
{ 
    return entities.Select(x => new PersonModel { 
     Me = x.Me.ToViewModel(), //this method cannot be translated into a store expression 
     Friends = x.Friends.AsQueryable().ToViewModels() //works fine with some magic (tm) 
    }); 
} 

public static IQueryable<ProfileModel> ToViewModels(this IQueryable<Profile> entities) 
{ 
    return entities.Select(x => new ProfileModel { Name = x.Name }); 
} 


public static ProfileModel ToViewModel(this Profile entity) 
{ 
    return new ProfileModel { Name = entity.Name }; 
} 

照会可能を使用して(例えばFriends = x.Friends.AsQueryable().ToViewModels())我々は平らにするためにいくつかの魔法を使用することができますこれは式になります(https://stackoverflow.com/a/10726256/1070291、@LordTerabyteの回答を参照)。しかし、新しい節(例えばMe = new ProfileModel { Name = x.Me.Name })を使って代入を行うときには、式ではなく、これを拡張メソッドの下にバンドルすると(例えばMe = x.Me.ToViewModel())これを式にフラット化することはできません。

新しいオブジェクトへの割り当ては、EFのシーンでどのように機能しますか?

拡張メソッドを使用して新しいオブジェクトに変換する方法はありますか?ここ

完全なデモコード:https://github.com/lukemcgregor/ExtensionMethodProjection

編集:

私は今、ブログの記事(Composable Repositories - Nesting Extensions)を持っているとnuget package LINQ

+0

あなたの現在のコードで動作しますか? –

+0

'Me = x.Me.ToViewModel()'は動作しません。残りのデモアプリケーションをGHに投稿したいのであれば –

+0

実際には 'Person'モデルと' PersonModel'を見るのに役立ちます。完全なコードですが、関連する部分です。 –

答えて

2

に営巣拡張メソッドを支援するためには、見てみましょうthis answer。それはあなたが望むものと非常によく似ています。

public static Expression<Func<Profile, ProfileModel>> ToProfileViewModel() 
{ 
    return entity => new ProfileModel { Name = entity.Name }; 
} 

をして、この(例えばExpressionsHelper.ToProfileViewModel()AsQuote()(P))の呼び出しを行います。基本的には、例えば、式ツリーとしてあなたの変換を定義します。

あなたが好きな方は、訪問者を修正してより良い構文を許可することができます。線に沿って何か:

[ReplacementInExpressionTrees(MethodName=nameof(ExpressionsHelper.ToProfileViewModel))] 
public static ProfileModel ToViewModel(this Profile profile) 
{ 
    // this implementation is only here, so that if you call the method in a non expression tree, it will still work 
    return ExpressionsHelper.ToProfileViewModel().Compile()(profile); // tip: cache the compiled func! 

は今、あなたはすべてのメソッド呼び出しをチェックして、この属性を持つ方法を見つけたとき、それはExpressionsHelper.ToProfileViewModel()への全体の呼び出しを変更し、訪問者を、作成する必要がありますAsQuote()。 (プロフィール)。これはあなたのための練習としてです:) }

+0

あなたはまた、そのような構造体を目的の式に直接変換することもできます – MBoros

+0

これはすばらしく、 'ReplacementInExpressionTreesAttribute'を参照しました。私はこれを書く必要があると思いますか?これは、メソッド呼び出しを、ツリーで使用されたときにリストされている式に置き換えると思われます。これはまさに私の後のものです:) –

+0

ああ、私はこれを書いて、病気があると言っているあなたを得る... –

関連する問題