我正在重构我的代码,我首先删除了服务层中对Entity Framework的引用。该层使用位于我的DAL层中的工作单元和存储库(通过接口)。
现在我遇到了一个问题,因为我的基本存储库类看起来像这样:
public interface IDatabaseFactory<C> : IDisposable
{
C Get();
void Set(string connectionString);
}
public abstract class Repository<C, T> : IRepository<T>
where C : DbContext, IBaseContext
where T : class, IEntity
{
protected readonly IDbSet<T> dbset;
private C dataContext;
protected Repository(IDatabaseFactory<C> databaseFactory)
{
this.DatabaseFactory = databaseFactory;
this.dbset = DataContext.Set<T>();
}
protected IDatabaseFactory<C> DatabaseFactory
{
get;
private set;
}
protected C DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}
public virtual void Add(T entity)
{
dbset.Add(entity);
}
//etc...
}
我显然需要在类型C上使用DbContext约束。但是,如果我这样做,我会在dataContext上遇到错误,因为它无法在DbContext中解析C.
我该如何克服这个问题?
修改
典型的存储库如下所示:
public interface ICustomerTypeRepository : IRepository<CustomerType> { }
public class CustomerTypeRepository : Repository<IBaseContext, CustomerType>, ICustomerTypeRepository
{
public CustomerTypeRepository(IDatabaseFactory<IBaseContext> databaseFactory)
: base(databaseFactory) { }
}
在下面建议的更改之后,我仍然会遇到相同的错误:
类型&#39; IBaseContext&#39;不能用作类型参数&#39; TContext&#39;在通用类型或方法&#39;存储库&#39;。来自&#39; IBaseContext&#39;没有隐式参考转换。 to&#39; System.Data.Entity.DbContext&#39;。
答案 0 :(得分:0)
要修复编译错误,您必须为通用类型设置适当的约束(我已将C
替换为TContext
以提高可读性):
interface IBaseContext { }
interface IDatabaseFactory<TContext> : IDisposable
where TContext : DbContext
{
TContext Get();
void Set(string connectionString);
}
interface IEntity { }
interface IRepository<T>
where T : class, IEntity
{ }
abstract class Repository<TContext, T> : IRepository<T>
where TContext : DbContext, IBaseContext
where T : class, IEntity
{
protected readonly IDbSet<T> dbset;
private TContext dataContext;
protected Repository(IDatabaseFactory<TContext> databaseFactory)
{
this.DatabaseFactory = databaseFactory;
this.dbset = DataContext.Set<T>();
}
protected IDatabaseFactory<TContext> DatabaseFactory { get; private set; }
protected TContext DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}
public virtual void Add(T entity)
{
dbset.Add(entity);
}
//etc...
}
但是从架构的角度来看,在存储库中持有对DbContext
的引用似乎是多余的。当然,如果没有关于所有类型的知识,很难提出更好的解决方案。
答案 1 :(得分:0)
要从代码中删除DbContext,您需要更改IDatabaseFactory,如下所示:
public interface IDatabaseFactory : IDisposable
{
T Set<T>() where T : IEntity;
}
然后您可以更改存储库
public abstract class Repository<T> : IRepository<T>
where T : class, IEntity
{
protected readonly IDbSet<T> dbset;
protected Repository(IDatabaseFactory databaseFactory)
{
this.dbset = databaseFactory.Set<T>();
}
// other code
}
IDatabaseFactory的实现:
public class DatabaseFactory : IDatabaseFactory
{
private readonly DbContext _context;
public DatabaseFactory(DbContext context)
{
_context = context;
}
public T Set<T>() where T : Entity
{
return _context.Set<T>();
}
}