Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF 5.0和存储库模式的有界上下文_C#_Entity Framework_Generics_Repository Pattern - Fatal编程技术网

C# EF 5.0和存储库模式的有界上下文

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

我构建了一个EF5.0存储库模式。下面是上下文、存储库和单元测试

我这里的问题是关于有界上下文。实体A和B是ABContext的一部分,但实体C不是ABContext的一部分。现在,当我运行测试以获取ABContext上的实体时,我得到了ABContext上所有三个实体(T=A,B,C)
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:)。你没有看到我所看到的泛型的问题吗?