2015-12-02 54 views
0

假設我有一個叫Item模型,看起來像這樣:應用LINQ到一個DbSet內的DbContext

public int ID { get; set; } 
public DateTime DateCreated { get; set; } 
public DateTime? DateArchived { get; set; } 
[Required] 
public string Alias { get; set; } 

它已被列入的DbContext ...

public DbSet<Item> Items { get; set; } 

每當我想選擇數據庫中的所有項目,我只想包含Archived == null和排序Alias的項目。

當DbSet被調用時(例如在DbContext上)有沒有一種方法可以設置EF來執行此操作?例如,如果我在控制器中調用db.Items,我總是希望應用這些選項,而不必明確聲明它們。

我目前的做法是用前綴「All」重命名DbSet並添加一個應用了這些選項的函數(函數使用DbSet的原始名稱,以便腳手架控制器和頁面使用自定義查詢而不需要任何更改):

public DbSet<Item> AllItems { get; set; } 
public IQueryable<Item> Items 
{ 
    get { return AllItems.Where(item => item.Archived == null).OrderBy(item => item.Alias); } 
} 

但是,這種方法的東西感覺hackish/wrong。這是做這件事的好方法嗎?這通常應該怎麼做?

+1

我不認爲這是黑客或錯誤。出於某種原因,如果您還需要所有物品,該怎麼辦? – MutantNinjaCodeMonkey

+0

@我同意@MutantNinjaCodeMonkey。對我來說這似乎很完美 –

回答

0

我曾經有類似的問題,我創建了一個數據庫視圖來呈現我的數據與所有必要的限制。視圖可以與表格具有相同的字段,但不是必需的。然後,您創建另一個DbSet項目,例如DbSet<ItemView>,它在數據庫中核對而不是表。在這個視圖內部,你可以根據你的意願聲明你的聲明。如果屬性相同,則也可以爲這兩個類創建相同的祖先(例如,ItemItemView都從ItemBase繼承)。

我已經在MS SQL Server上完成了這項工作。

0

我通常避免直接訪問DbSet,並通過隱藏接口背後的上下文來強制實現這個想法。然後我只能從界面訪問存儲庫方法。如果您希望客戶端代碼無法訪問表集合(並希望將它們引導至某些過濾的數據子集),那麼這會在您的客戶端代碼中使用DbSets時將其隱藏起來。

public interface IDataContext : IDisposable 
{ 
    void SaveChanges(); 
    IQueryable<Item> GetItems(); 
} 

public class DataContext : DbContext, IDataContext 
{ 
    public DataContext(string connectionStringName) : base(connectionStringName) { } 

    public DbSet<Item> Items { get; set; } 

    public IQueryable<Item> GetItems() 
    { 
     return Items.Where(item => item.Archived == null).OrderBy(item => item.Alias); 
    } 
} 

using (IDataContext context = new DataContext("myConnection")) 
{ 
    var items = context.GetItems(); 
} 
相關問題