我构建了一个EF 5.0存储库模式。以下是上下文,存储库和单元测试。
我的问题是关于有界上下文。实体A和B是ABContext的一部分,但实体C不是ABContext的一部分。现在当我运行测试以获取ABContext上的实体时,我得到了ABContext上所有三个实体(T = A,B,C)GetAll<T>
的结果。
我希望&#34; clist&#34;失败或为实体C抛出异常,因为对于T = C,ABContext不存在context.Set<T>();
。
BTW ..实体C是不同背景的一部分。
上下文:
public class ABContext : BaseContext<ABContext>
{
public DbSet<A> As{ get; set; }
public DbSet<B> Bs{ get; set; }
}
public class BaseContext<TContext>: DbContext where TContext : DbContext
{
protected BaseContext()
: base("name=DBEntities")
{
this.Configuration.LazyLoadingEnabled = false;
}
}
存储库:
public abstract class BaseRepository : IRepository
{
protected BaseRepository()
{
}
public DbContext context { get; set; }
public virtual IQueryable<T> GetAll<T>() where T: class
{
return context.Set<T>();
}
}
public class ABRepository : BaseRepository
{
public ABRepository()
{
this.context = new ABContext();
}
}
单元测试:
[TestMethod]
public void GetAllTests()
{
using (var repo = new ABRepository())
{
List<A> alist = repo.GetAll<A>().ToList();
List<B> blist = repo.GetAll<B>().ToList();
List<C> clist = repo.GetAll<C>().ToList();
}
}
答案 0 :(得分:1)
首先,这与我通常的做法略有不同,此时我无法对此进行测试,所以如果此处有任何错误,我会提前道歉。
BaseRepository.GetAll
在Set<T>
上致电DbContext
。该方法将创建DbSet
T
,这就是GetAll<C>
将返回DbSet
并通过测试的原因。您甚至可以省略DbSet
和A
的{{1}}属性,您的测试仍会通过。您应该覆盖并控制B
的创建,而不是依赖DbContext.Set<T>
。我通常使用DbSets
并覆盖Dictionary<Type, Func<object>>
从字典中返回:
Set
现在public class MyContext : DbContext
{
private readonly Dictionary<Type, Func<object>> _dbSets;
public MyContext() : base(nameOrConString) {
_dbSets = new Dictionary<Type, Func<object>> {
{typeof (A), () => base.Set<A>()},
{typeof (B), () => base.Set<B>()}
};
}
public override DbSet<TEntity> Set<TEntity>() {
if (!_dbSets.ContainsKey(typeof (TEntity)))
return null; // or throw exception or whatever
return _dbSets[typeof (TEntity)]() as DbSet<TEntity>;
}
}
只会返回您已将其配置为创建/返回的Set
。
致电DbSets
将返回MyContext.Set<A>()
。
致电DbSet<A>
将返回MyContext.Set<B>()
。
调用DbSet<B>
将返回MyContext.Set<C>()
,因为它不存在于词典中。