现在我将Entity Framework与以下DbContext类一起使用:
public class ItemDbContext : DbContext {
...
public DbSet<Item1> Item1s { get; set; }
public DbSet<Item2> Item2s { get; set; }
}
有些类需要使用Item11s
或Item2s
作为依赖关系的DbContext。所以我的目的是为DbContext创建一个抽象层,使用DbSet类型(逻辑上将DbContext_Item1和DbContext_Item2分开)。它也可用于实现抽象工厂模式(创建DbContext_Item1或DbContext_Item2实例)。
我的想法:
1)接口
public interface IDbContext_Item1 {
DbSet<Item1> Item1s { get; set; }
}
public interface IDbContext_Item2 {
DbSet<Item3> Item2s { get; set; }
}
所以我的抽象工厂能够拥有这样的API:
public abstract ItemFactory {
public abstract IDbContext_Item1 GetItem1Context;
public abstract IDbContext_Item2 GetItem2Context;
}
对我来说没问题。但是获取IDbContext_ItemX实例的类并不将其视为DbContext实例(即不能调用类似SaveChanges()等的方法)。不幸的是,任何接口都不能从像DbContext这样的类继承。
2)使用DbContext
方法的扩展接口public interface IDbContext_Item1 {
DbSet<Item1> Item1s { get; set; }
void SaveChanges;
// etc
}
在我看来,它非常不优雅。
3) IDbContext_ItemX
的抽象类但我当前的DbContext实现ItemDbContext
不能从多个类继承。
4)在DbContext_Item1和DbContext_Item2 具体类上只需 devide 当前ItemDbContext
。
是的,这是决定。但这只是方法吗?如果我的具体工厂在引擎盖下返回ItemDbContext
的实例,那就太好了。我能实现吗?
答案 0 :(得分:1)
正如我评论的那样,我首先挑战想要在给定上下文中使用单个实体的原因,但如果您决定继续使用该实体,我会使用通用接口,或者甚至是一般的背景:
interface IDbContext<T> where T : class
{
IDbSet<T> Set { get; }
}
// Context implement generic Interface
class DbContextItem1 : IDbContext<Item1>
{
IDbSet<Item1> Set { get; private set; }
override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Logic to get relevant mappings,
}
}
// Technically you could also do that.
class DbContextItem1 : IDbContext<Item1>, IDbContext<Item2>
{
IDbSet<Item1> IDbContext<Item1>.Set { get; }
IDbSet<Item2> IDbContext<Item2>.Set { get; }
override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Logic to get relevant mappings,
}
}
// Generic context.
class DbContextGeneric<T> : IDbContext<T>
{
IDbSet<T> Set { get; private set; }
override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Logic to get relevant mappings based on T.
}
}
答案 1 :(得分:0)
我认为您需要创建一些基本界面(让我们称之为IDatabaseContext
):
public interface IDatabaseContext : IDisposable
{
//base DbContext stuff like SaveChanges here
}
然后你有嵌套的接口:
IDbContext_Item1 : IDatabaseContext
IDbContext_Item2 : IDatabaseContext
您的ItemDbContext
实现了两个接口。
我同意在DbContext
界面中编写所有IDatabaseContext
方法并不优雅,但您只需要执行一次