C# EF 5.0和存储库模式的有界上下文
我构建了一个EF5.0存储库模式。下面是上下文、存储库和单元测试 我这里的问题是关于有界上下文。实体A和B是ABContext的一部分,但实体C不是ABContext的一部分。现在,当我运行测试以获取ABContext上的实体时,我得到了ABContext上所有三个实体(T=A,B,C)C# EF 5.0和存储库模式的有界上下文,c#,entity-framework,generics,repository-pattern,C#,Entity Framework,Generics,Repository Pattern,我构建了一个EF5.0存储库模式。下面是上下文、存储库和单元测试 我这里的问题是关于有界上下文。实体A和B是ABContext的一部分,但实体C不是ABContext的一部分。现在,当我运行测试以获取ABContext上的实体时,我得到了ABContext上所有三个实体(T=A,B,C)GetAll的结果 我希望“clist”失败或抛出实体C的异常,如context.Set() 顺便说一句。。实体C是不同上下文的一部分 背景: public class ABContext : BaseConte
GetAll
的结果
我希望“clist”失败或抛出实体C的异常,如context.Set()
顺便说一句。。实体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;
}
}
公共类ABContext:BaseContext
{
公共数据库集为{get;set;}
公共数据库集Bs{get;set;}
}
公共类BaseContext:DbContext,其中TContext:DbContext
{
受保护的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();
}
}
公共抽象类BaseRepository:IRepository
{
受保护的BaseRepository()
{
}
公共DbContext上下文{get;set;}
公共虚拟IQueryable GetAll(),其中T:class
{
返回context.Set();
}
}
公共类ABRepository:BaseRepository
{
公共广播
{
this.context=新的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();
}
}
[TestMethod]
public void GetAllTests()
{
使用(var repo=new ABRepository())
{
列表列表=repo.GetAll().ToList();
List blist=repo.GetAll().ToList();
List clist=repo.GetAll().ToList();
}
}
首先,这与我通常的做法有些不同,我现在无法测试,因此如果这里有任何错误,我提前道歉
BaseRepository.GetAll
在DbContext
上调用Set
。该方法将创建T
的DbSet
,这也是GetAll
将返回DbSet
并通过测试的原因。您甚至可以省略A
和B
的DbSet
属性,您的测试仍然会通过。不要依赖DbContext.Set
您应该重写并控制dbset
的创建。我通常使用字典
并覆盖集合
从所述字典返回:
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>;
}
}
公共类MyContext:DbContext
{
专用只读词典_数据库集;
public MyContext():base(nameOrConString){
_新字典{
{typeof(A),()=>base.Set()},
{typeof(B),()=>base.Set()}
};
}
公共覆盖数据库集(){
如果(!_dbSets.ContainsKey(typeof(tenty)))
返回null;//或抛出异常或其他
返回_DbSet[typeof(tenty)]()作为DbSet;
}
}
现在Set
将只返回您配置为创建/返回的dbset
调用MyContext.Set()
将返回一个DbSet
调用MyContext.Set()
将返回一个DbSet
调用
MyContext.Set()
将返回null
,因为它在字典中不存在。我尝试实现您的解决方案,现在我面临与泛型相关的另一个问题。当我将returnobj转换为DBSet时失败了。错误说明:类型TEntity必须是引用类型才能将其用作参数。然后,我试图通过在方法中添加“where tenty:class”来提供对tenty的引用,但它抱怨约束是从基方法继承的,因此无法直接指定:(诸如此类,我确信至少会有一个问题。你还在扩展你的BaseContext吗?谢谢你的帮助,史密斯!!我尝试了两种方法。直接从DbContext扩展MyContext,也从“BaseContext:DbContext”扩展MyContext)。无论哪种方式,我都会遇到相同的错误。很抱歉延迟。我注意到我的答案中有一个错误,我使用了\u dbSets.Contains(…)
,而不是\u dbSets.ContainsKey(…)
。除此之外,这对我有效。我直接从答案复制并粘贴了。是的,我在解决方案中修复了ContainsKey:)。你没有看到我所看到的泛型的问题吗?