2011-11-10 13 views
0

一部の追加行で結合されたナビゲーションプロパティでマッピングされたエンティティを含むエンティティフレームワークモデルに部分クラスのプロパティを追加しようとしています。エンティティフレームワーク内の非関連エンティティを部分クラスに含めるにはどうすればよいですか?

データベース: 私はUserID主キーを持つUsersテーブルを持っています。また、UserUserID(外部キー、nullable)を持つTagsテーブルがあります。これはユーザー固有の場合はUserIDに設定されますが、すべてのユーザーに適用されることを示す場合はnullでもかまいません。

EFモデル: ナビゲーションプロパティUsers.Tagsは、そのユーザーに明示的に割り当てられているすべてのタグを含むように正しく生成されます。

問題: 私は、ユーザーヌルされているもののOwnerUserIDを持っているすべてのタグを含むユーザエンティティのプロパティを必要としています。 だから私のような何かを言うことができるようにしたい:{AllTags}はシステム内のすべてのタグを表し

public partial class User 
    { 
     public IEnumerable<Tag> VisibleTags 
     { 
      get 
      { 
       return tags = (from t in {AllTags} 
           where t.PrivateUserID == null 
           select t).Union(
           from t in this.Tags 
           select t); 
      } 
     } 
    } 

を...。

答えて

3

デザインのクイックコメント:

私は、データベース内のNULL可能値の大ファンではない、特に対照的なnullは、にすべてユーザーを適用する値のように、コンテキスト情報を提供します〜ユーザー。

ユーザーをグループ化でき、ユーザーのグループにタグが表示されるように設計することを検討してください。これは、あなたのニーズが将来変更された場合にはより柔軟になり、より明示的になります。また、列をnullにできないようにすることもできます。

これをシステムに組み込みたくない場合は、自分の現在のデザインからグループベースのデザインへの移行を、あなたがペイントしていないことを確認するためにプロットしますあなた自身をデザイン上の隅に合わせてください。

あなたはコンテキストからAllTagsを取得するので、あなたは、コンテキストオブジェクトを使用する必要があるとしている手

の問題。これを行うには

試み1

一つの方法は、どちらかUserまたはUserIdを受け入れるコンテキストでメソッドを作成することです。

// In partial Context class... 

public IEnumerable<Tag> GetVisibleTags(User user) 
{ 
    return Tags.Where(t => t.PrivateUserID == null) 
     .Union(user.Tags) 
     ; 
} 

// Call it like this... 

context.GetVisibleTags(someUser); 

私はコンテキストを使用してクエリを作成する必要はないと思うので、私は完全に好きではありません。それは "リポジトリ"(エンティティ/ DbSet/DataSetクラス)の仕事です。

試み2

別の方法(ユーザーオフそれにアクセスできるようになる)あなたのゲッターメソッドにコンテキストパラメータを追加することです:

// In partial User class... 

public IEnumerable<Tag> GetVisibleTags(MyContextClass context) 
{ 
    return context.Tags.Where(t => t.PrivateUserID == null) 
     .Union(this.Tags) 
     ; 
} 

// Call it like this 

someUser.GetVisibleTags(context); 

私よりもさらに少ないこれが好きまず、 "リポジトリ"(エンティティ/ DataSet/DbSet)がコンテキストについて何も知っていてはならないからです。あなたはこの問題を解決するために、クエリのラッパーオブジェクトを作成することができ

試み3

。できる限り複雑なクエリをこの方法で書くことをお勧めします。したがって、再利用可能です。

トリック

// Todo: This is a terrible name. 
// Figure out what makes more sense in your domain, by seeing where you use it 
public class VisibleTags 
{ 
    private readonly IMyContextClass context; 

    public VisibleTags(IMyContextClass context) 
    { 
     this.context = context; 
    } 

    // Todo: Try to see if you can get this to return IQueryable. 
    // I haven't used Union, so I'm not sure if it breaks that ability or not... 
    public IEnumerable<Tag> GetVisibleTags(User user) 
    { 
     return context.Tags 
      .Where(t => t.PrivateUserID == null) 
      .Union(user.Tags) 
      ; 
    } 
} 
+0

を明確にするために、私は実際にユーザーにタグを適用していないよ...クラスのために良いドメイン固有名の名前を考え出すされています。タグはシステム内の他のオブジェクトに適用されます。この関係は、ユーザーへの可視性を定義するだけのものです。したがって、一部のタグはパブリック(すべてのユーザーに適用されます)およびプライベート(現在のユーザーのみに表示されます)です。 – Joe

+0

@ジョー:オハイオ、大変申し訳ありません、私は完全にその事実を逃しました。それでも、この設計では、1人のユーザーだけがタグを見ることができ、またはすべてのユーザーがタグを見ることができます。将来的に管理者ユーザーがいくつかのタグを見る能力を望んでいない限り、いくらか意味をなさないかもしれないと思います。あなたの目に見えるタグの明示的なクエリを行うことができると思います... –

+0

私はそれを取るために私の答えを編集します:) –

関連する問題