EF 5.0和存储库模式的有界上下文
本文关键字:上下文 模式 存储 EF | 更新日期: 2023-09-27 18:18:08
我构建了一个EF 5.0存储库模式。下面是上下文、存储库和单元测试。
我的问题是关于有界上下文。实体A和B是ABContext的一部分,但实体C不是ABContext的一部分。现在,当我运行测试以获取ABContext上的实体时,我得到ABContext上所有三个实体(T = A, B, C) GetAll<T>
的结果。
我希望"clist"对实体C失败或抛出异常,因为T = C的ABContext不存在context.Set<T>();
顺便说一句. .实体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();
}
}
首先,这与我通常的做法有点不同,我现在无法测试这个,所以如果这里有任何错误,我提前道歉。
BaseRepository.GetAll
对DbContext
呼叫Set<T>
。该方法将创建T
的DbSet
,这也是GetAll<C>
将返回DbSet
并通过测试的原因。您甚至可以省略A
和B
的DbSet
属性,您的测试仍然可以通过。而不是依赖于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>()
将返回null
,因为它在字典中不存在。