5

我正在尝试定义自己的 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(会抛出一个"value cannot be null"; 如果我替换并使用 DbSet 代替

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

一切正常。

有谁知道我是否以及如何解决这个问题,以便我可以使用自己的派生类?

编辑:

在收到一些评论后,我澄清了我这样做的原因:我希望能够在不更改代码的情况下轻松地从数据检索机制切换到另一种机制。例如,如果我决定在内存中进行缓存(缓存只是一个示例,可能我还想更改其他一些东西)我只是覆盖Any/Find/...inMyDbSet并从字典中读取而不是查询数据库,剩下的代码不变。这样,代码将执行“常规”操作,而无需考虑如何在后面检索数据。因此,如果有人可以指出一种方法来做到这一点,而无需扩展DbSet也可以回答问题的类。

非常感谢

4

1 回答 1

1

我已经在这条路上走过了几次,并且理解让它以这种方式工作的愿望,但根据我的经验,这是不可行的,或者如果是的话,不值得付出努力。原因是许多不同的存储引擎(包括内存缓存)具有无法轻松融入 EF 的差异。例如,一个简单的 DbSet 内存缓存实现可能不支持事务、延迟或急切加载方案等。我的想法是我希望能够在 Azure 表存储中进行交换。但是,排序、分页和查询不如 SQL Server 丰富。可以使用 SQL 执行的某些查询是 Azure 表无法执行的。最后,我总是回过头来相信,在 EF 背后更换持久性引擎的能力听起来很有吸引力,

如果我想支持缓存并且正在做一个 ASP.NET Web API,我会考虑使用 ASP.NET 缓存,以便在那时缓存 API 请求/响应。

如果我想支持不同的关系数据库供应商,我会使用第 3 方 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 Tables”。这可能只是由于我们所做的工作类型,但最终,它最终成为我只是接受并直接编码到 EF 的依赖项。

于 2015-03-03T15:47:24.927 回答