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();
    }
}

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

首先,这与我通常的做法有点不同,我现在无法测试这个,所以如果这里有任何错误,我提前道歉。

BaseRepository.GetAllDbContext呼叫Set<T>。该方法将创建TDbSet,这也是GetAll<C>将返回DbSet并通过测试的原因。您甚至可以省略ABDbSet属性,您的测试仍然可以通过。而不是依赖于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,因为它在字典中不存在。