簡體   English   中英

實體框架:如何擴展DbSet <type> ?

[英]Entity framework: how to extend DbSet<type>?

我正在嘗試定義自己的DbSet,如:

public class MyDbSet<TEntity> : DbSet<TEntity>
    where TEntity : class
{
    public override TEntity Add(TEntity entity)
    {
      ....

並在DbContext中使用它

    public MyDbSet<User> Users { get; set; }

我面臨的問題是Users在運行時將為空(因此無用)但我無法理解為什么。 db.Users.Any(類的db.Users.Any(將拋出"value cannot be null" ;如果我替換並使用DbSet而不是

    public DbSet<User> Users { get; set; }

一切正常。

有誰知道我是否以及如何解決這個問題所以我可以使用自己的派生類?

編輯:

在收到一些評論之后,我澄清了為什么我這樣做:我希望能夠輕松地從數據檢索機制切換到另一個而無需更改代碼。 例如,如果我決定在內存中進行緩存(緩存只是一個例子,我可能也想改變其他一些東西)我只是覆蓋MyDbSetAny/Find/...並從字典中讀取而不是查詢數據庫,保持其余代碼不變。 這樣,代碼將執行“常規”操作,而無需考慮如何檢索數據。 因此,如果有人可以指出一個方法來執行此操作而不擴展也將回答問題的DbSet類。

非常感謝

我已經走過這條路幾次了,並且理解讓它以這種方式工作的願望,但根據我的經驗,這是不可行的,或者如果它是,不值得努力。 原因是許多不同的存儲引擎(包括內存緩存)具有不能輕易融入EF的差異。 例如,DbSet的一個簡單的內存緩存實現可能不會遵循事務,懶惰或急切加載方案等。我的想法是我希望能夠交換Azure表存儲。 但是,通過排序,分頁和查詢並不像SQL Server那樣豐富。 您可以使用SQL執行的某些查詢無法使用Azure表。 最后,我總是回過頭來相信,替換EF背后的持久性引擎的能力聽起來很吸引人,但是比實現幾個類更復雜 - 在我的應用程序中通常不值得。

如果我想支持緩存並且正在使用ASP.NET Web API,我會考慮使用ASP.NET緩存,以便在那時緩存API請求/響應。

如果我想要支持不同的關系數據庫供應商,我會使用第三方EF提供商: 各種數據庫的實體框架提供商列表順便提一下,他們確實鏈接到緩存和跟蹤EF提供商 - 不知道這是否適用於新的EF。

如果我想在數據層內部進行緩存,或者需要多個存儲引擎(即Mongo,Azure和SQL),我會在EF層“上方”進行緩存。 像這樣的東西:

 public interface ISomeDataProvider
 {
     SomeType Find(int id); 
     ....
 }

 public class EfDataProvider : ISomeDataProvider
 {
     private SomeAppDbContext db = new SomeAppDbContext();
     public SomeType Find(int id){
         return db.SomeTypes.Find(id);
     }

 }

 public class AzureTableDataProvider : ISomeDataProvider
 {
     public SomeType Find(int id){
         return //Azure Table code
     }

 }

 public class CachingDataProvider : ISomeDataProvider
 {
     private ISomeDataProvider source;
     private static IList<SomeType> cache = new List<SomeType>(); //List used here, but could use .NET Cache, Redis, etc.
     public CachingDataProvider(ISomeDataProvider source){
            this.source = source;
     }
     public SomeType Find(int id){
         var result = cache.SingleOrDefault(x=>x.Id == id)
         if(result == null){
             result = source.SingleOrDefault(x=>x.Id == id)
             if(result != null) cache.Add(result); //Again, trivial cache example.  Cache expiration, refresh, loading, etc. should be considered per-app
         }
         return result
     }

 }

也就是說,對於我的大多數應用程序,當我考慮它時,交換持久性引擎的能力並不是真正的要求。 我的客戶不“有些想要SQL,有些想要Azure表”。 這可能只是由於我們所做的工作類型,但最終,它最終成為我只接受並直接編碼到EF的依賴。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM