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

时间:2014-08-14 20:33:39

标签: c# entity-framework generics repository-pattern

我构建了一个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();
    }
}

1 个答案:

答案 0 :(得分:1)

首先,这与我通常的做法略有不同,此时我无法对此进行测试,所以如果此处有任何错误,我会提前道歉。

BaseRepository.GetAllSet<T>上致电DbContext。该方法将创建DbSet T,这就是GetAll<C>将返回DbSet并通过测试的原因。您甚至可以省略DbSetA的{​​{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>(),因为它不存在于词典中。