繁体   English   中英

EF6:从派生的DbSet获取数据

[英]EF6: getting data from derived DbSet

我做我工作的最终目的是为DbContext提供一些缓存功能。 为了实现此目的,我试图通过在上下文中重写Set<T>()方法并返回直接从常规DbSet类派生的类型的对象来扩展默认的DbSet功能。 像这样:

public class Context : DbContext
{
    ...

    public override DbSet<TEntity> Set<TEntity>()
    {
        //var set = base.Set<TEntity>();
        var set = new XxSet<TEntity>();
        return set;
    }
}

class XxSet<TEntity> : System.Data.Entity.DbSet<TEntity>
    where TEntity : class
{
    public override TEntity Find(params object[] keyValues)
    {
        return base.Find(keyValues);
    }
}

看起来清晰而简单,但是当我对此进行测试时,EF给我一个错误:

成员'IQueryable.Provider'尚未在继承自'DbSetˊ1'的类型'XxSetˊ1'上实现。 “ DbSetˊ1”的测试双精度必须提供所用方法和属性的实现。

它要求我实现IQueryable接口。 我知道,但是为什么呢? 它应该已经在基类中实现了吗? 我想这一定是必须的,否则Set<T>()方法的基本功能Set<T>()如何工作,该方法将返回由System.Data.Entity.DbSet<TEntity>类型实例化的对象。

我在这里想念什么吗?

BTW。 我知道有关创建内存中DbSet的Microsoft示例。 我只想了解为什么我不能做这种简单的方法。

我不知道为什么它不起作用,这看起来像可以完成但实体不喜欢的事情,在此链接中:

NSubstitute DbSet / IQueryable <T>

有类似的错误,很抱歉,如果它根本无法帮助您–

那是答案吗? 很高兴为您提供帮助。

我在实现继承IDbSet的接口的类中遇到了一些问题。 这是因为所有(或至少大多数)IQueryable方法都没有在DbSet中实现,而是Queryable类的扩展方法。 大多数模拟框架不能模拟静态扩展方法。 我通过将方法添加到派生的接口并在我的类IDerivedDbSet中实现这些方法来克服了这些问题:

 public IQueryable<T> Where(Expression<Func<T, bool>> predicate)
    {
        return this._dbSet.Where(predicate);
    }

    public bool Any(Expression<Func<T, bool>> predicate)
    {
        return this._dbSet.Any(predicate);
    }

但是,测试使用这些方法的位置有点脏,因为您现在必须模拟该方法,而不是依赖模拟在注入的IQueryable上实际执行的扩展。 这是一个例子:

 this._context = Substitute.For<IDerivedContext>();
 this._permissionSet = Substitute.For<IDerivedSet<Permission>> ();
 this._permission1 = new Permission
        {
            UserID = 1,
            MenuID = 26,
            PermissionAllow = true
        };
 var queryable = (new List<Permission> { this._permissionLink1 }).AsQueryable();
 this._permissionSet.Any(Arg.Any<Expression<Func<Permission, bool>>>()).Returns(x => queryable.Any((Expression<Func<Permission, bool>>)x[0]));

 var result = this._permissionsProvider.HasPermissionToSomething(this._context, 1);
 Assert.IsTrue(result);

肮脏的是,然后将IDerivedDbSet.Any方法的expression参数用作直接在queryable上调用的Queryable.Any扩展方法的expression参数。 这不是很好,因为它假定两个Any方法都做同样的事情,但是它确实允许我模拟实际实现的查询并断言被测试的类在此基础上返回了正确的结果。 如果我在已测试的类方法中更改查询,则测试将失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM