繁体   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