2012-05-26 28 views
2

我正在使用實體框架和SQL Server 2008作爲數據存儲的ASP.Net MVC3網站。此外,我正在使用Repository模式將所有數據訪問代碼集中在一個區域中。實體框架每個用戶的行級安全

在我的應用程序中,我有很多用戶,每個用戶都可以有很多項目。用戶只能訪問他們自己的項目。 目前,我有這樣的代碼:

public IQueryable<Project> All 
    { 
     get { 
      return context.Projects 
       .Where(p => p.Owner.ID == Util.GetCurrentUserID()) 
       .Select(p=>p); 
     } 
    } 

    public Project Find(System.Guid id) 
    { 
     return context.Projects 
       .Where(p => p.Owner.ID == Util.GetCurrentUserID()) 
       .FirstOrDefault(); 
    } 

如果您發現.Where(p => p.Owner.ID == Util.GetCurrentUserID())被複制。而且我還有其他幾個地方在這些確切的條件下散落。

DbContext有沒有辦法讓這個條件總是自動附加到任何正在進行Projects表的查詢中?

喜歡的東西:

public class MyContext : DbContext 
{ 
    public DbSet<Project> Projects 
     .Where(p => p.Owner.ID == Util.GetCurrentUserID()) { get; set; } 
} 

OR

public class MyContext : DbContext 
{ 
    public DbSet<Project> Projects { get { 
      // Insert a cast from IQuerieable to DBSet below 
     return Projects 
       .Where(p => p.Owner.ID == Util.GetCurrentUserID()) 
       .Select(p => p); 
    } 
    set; } 
} 

UPD而寫的問題,實現了最後一個版本可以只是工作 - 需要嘗試。仍然希望聽到代碼優化的其他選項並使其更加乾爽。

在此先感謝!

+0

如果您找到自己的解決方案,請將其作爲答案發布,以便有同樣問題的人可以找到幫助。 – rcdmk

+0

@rcdmk,當然我會的。這就像一個共同的主題,不是嗎? – trailmax

回答

4

您可以隨時編寫名爲「WhereProject」的擴展方法。然後在將條件附加到謂詞後,在擴展方法中調用標準的「Where」方法。

public static IEnumerable<TSource> WhereProject<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) where TSource: Project 
{ 
    return source.Where(p=> p.Owner.ID == Util.GetCurrentUserID() && predicate); 
} 

,如果你願意,你可以跳過謂語或將其設置爲默認值的參數列表爲空,然後採取相應的行動,如果你不希望使用謂詞。


這可能是你想要什麼,這很簡單:

public static IEnumerable<TSource> WhereProject<TSource>(this IEnumerable<TSource> source) where TSource: Project 
{ 
    return source.Where(p=> p.Owner.ID == Util.GetCurrentUserID()); 
} 

編輯 這些解決方案不健全的權利我。我想你會希望保證你的行數據更高一級,在我的情況下,它將是服務層。考慮像這樣在服務類中的方法:

public List<Project> GetUserProjects(User user) 
{ 
    return repo.All().Where(p => p.Owner.ID == Util.GetCurrentUserID()).ToList(); 
} 

這樣,從方法的名稱,它是很清楚自己在做什麼。存儲庫不包含特定邏輯的責任。它只能處理您的數據訪問。

+0

是的,我想到了這種方法。我現在所做的更好,但並不理想 - 程序員必須記住在查詢中使用WhereProject()。如果我能夠將這些條件指定爲更高的水平,那將是太棒了。 – trailmax

+0

請檢查我的編輯。 –

+1

嗯..這實際上是我想要避免的 - 在庫之上有另一個層。存儲庫僅用於處理數據訪問。行安全(imho)屬於數據訪問。我明白這是非常有爭議的一點。我會等待幾天,並開始賞金 - 希望聽到關於此事的其他意見。 – trailmax