2011-11-10 54 views
0

我試圖在部分類添加一個屬性,其中包括已經通過聯合在一起了一些額外的行導航屬性被映射的實體的實體框架模型。如何在實體框架的部分類中包含非相關實體?

數據庫: 我有一個用戶表和用戶ID主鍵。另外,我有一個OwnerUserID(外鍵,可爲空),它被設置爲用戶ID,如果它是用戶特定的一個標籤表,也可以爲空,以表明它適用於所有用戶。

EF型號: 的導航屬性Users.Tags正確生成包括明確分配給該用戶的所有標籤。

問題: 我需要一個包括用戶的OwnerUserID所有的標籤和那些空的用戶實體的屬性。 所以我想能這樣說:

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); 
      } 
     } 
    } 

...其中{} AllTags代表系統中的所有標籤。

回答

3

上設計一個快速評論:

我不是空的值的大風扇在數據庫中,尤其null提供上下文信息,如適用於所有用戶的價值,而不是到沒有的用戶。

你可能要考慮一個設計,在那裏你可以組用戶和標籤將是可見的一組用戶。如果您的需求在未來發生變化,並且更加明確,這將更加靈活。它也會使它成爲可以使列不可空。

如果你不希望建立一個進入你的系統,現在,我會親自繪製出從當前設計到基於組的設計遷移會是什麼樣子,只是爲了確保你沒有畫你自己進入一個角落設計明智。

手頭的問題

你從上下文AllTags,所以你將不得不使用一個上下文對象。

嘗試1

一種方法,這樣做將是創建對接受任一UserUserId上下文的方法。

// 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

另一種方式(這會使它從用戶訪問)將是一個上下文參數添加到您的getter方法:

// 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

@Joe:哦,好吧,對不起,我完全錯過了這個事實。儘管如此,通過這種設計,只有一個用戶可以看到一個標籤,或者所有用戶都可以看到它。我想這可能是有道理的,除非你希望管理員用戶能夠看到一些標籤。在這種情況下,我想你可以明確地查詢該用戶的可見標籤... –

+0

我會編輯我的答案,以取出:) –