2012-05-11 21 views
0

Usersのコレクションを持っているSitesのセットがあります。たとえば、最後に訪問したUserを特定のsiteにするためにクエリを再定義する必要があるときはいつでも、自分自身がDRYプリンシパルに違反していることがわかります。一般的なクエリでエンティティモデルを拡張することは可能ですか?

例えば、私のクエリは次のようになります。

from site in Context.Sites 
where site.ID == 99 
select new { 
    ID = site.ID, 
    Name = site.Name, 
    URL = site.URL, 
    LastVisitedUser = site.Users.OrderByDescending(u => u.LastVisited).Select(u => new { 
     ID = u.ID, 
     Username = u.Username, 
     Email = u.EmailAddress 
    }) 
    .FirstOrDefault() 
} 

そのクエリは、私が欲しいものを返しますが、私は私がでサイトを選択していて自分が複数の場所でLastVisitedUserため、これと同じ選択を繰り返し見つけます私のさまざまなViewModelを取り込むさまざまな方法。

だから、私は単純にそうような財産と私のサイトEntitiyクラスを拡張することを考えた:

public partial class Site { 
    public LastVisitedUser { 
    get { 
     var query = from user in Users 
        where user.SiteID == this.ID 
        orderby user.LastVisited descending 
        select user; 
     return query.FirstOrDefault() 
    } 
    } 
} 

このように、私は、サイトを選択していたときに、この特性をつかむために、かなり些細なことでしょう。このはほぼですが、UserをViewModelのバージョンに投影する方法について明白な方法がなく、私の戻り値のLastVisitedプロパティにUserViewModelプロパティにEntityユーザーを割り当てようとしています。

おそらく例が説明するのに役立ちます。私が達成しようとしているのは次のようなものです:

from site in Context.Sites 
where site.ID == 99 
select new SiteViewModel { 
    ID = site.ID, 
    Name = site.Name, 
    URL = site.URL, 
    LastVisitedUser = site.LastVisitedUser <--- NOTE  
} 

注:これは私の失敗のポイントです。 LastVisitedUserは、サブモデルがUserのViewModelです。

私は正しい方法でこれについてお伝えしますか?私がしようとしていることを達成することはできますか?それとも、私は恐ろしく間違っていますか?私はこの問題を怒らせて、他の人にぶつかるつもりですか?

ありがとうございます!

+0

これらのメソッドはコントローラから呼び出されますか、これらのクエリにこれらのクエリが必要ですか? – RoelF

+0

私のリポジトリにあります。私のコントローラは、IEnumerableのバリアントまたは具体的なオブジェクトを扱っています。 – BradBrening

答えて

3

編集:以前の回答が正しくありませんでした。ナビゲーションプロパティで拡張メソッドを使用することはできませんが、Site投影全体の拡張メソッドを作成することはできます。

だけの単純な再利用可能な拡張メソッドを作成:今、あなたの前のクエリでその拡張子を使用することができるはず

public static IQueryalbe<SiteModel> GetSiteModels(this IQueryable<Site> query) 
{ 
    return query.Select(site => new SiteModel { 
        ID = site.ID, 
        Name = site.Name, 
        URL = site.URL, 
        LastVisitedUser = site.Users 
              .OrderByDescending(u => u.LastVisited) 
              .Select(u => new LastVisitedUser { 
               ID = u.ID, 
               Username = u.Username, 
               Email = u.EmailAddress 
              }}); 
} 

を:あなたの財産が表示されていないので、

Context.Sites.Where(site => site.ID == 99).GetSiteModels(); 

あなたの例では動作しません。 Linqとエンティティの関係

+0

私はこれを試していましたが、私が何をしても、私はエラーを受け取り続けます:EntityCollection にはGetLastUsers()の定義がなく、EntityCollectionタイプの最初の引数を受け入れる拡張メソッドはありませんが見つかりました。私は、私のリポジトリクラス内に拡張メソッドを置いて、名前空間などを混乱させないようにしました。何か不足していますか? – BradBrening

+0

あなたは正しいです、それは表現方法がナビゲーションプロパティの投影の中で使用できないので、うまくいきません。 Siteプロジェクション全体の拡張メソッドを作成する必要があります。 –

0

異なる拡張機能を使用して共通クエリを再利用することを意味する場合は、いくつかの基本クエリを書いて別の結果といくつかのWhereラムダ式を得ることを躊躇してください。あなたがそれをプロファイルすると、DBへのクエリが1つしかないことがわかります。ベースクエリでIQuerableを返すだけです。

関連する問題