一直在从许多资源中使用 EF5 Code First 实现通用存储库、工作单元模式,并提出了以下程序集。
接口、上下文、模型、存储库、工作单元
在上下文程序集中,我有我的迁移文件夹,其中包含 Configuration.cs
internal sealed class Configuration : DbMigrationsConfiguration<Context.SportsContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(Context.SportsContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
正如您所看到的,这个 DbMigrationsConfiguration 接受了我的 SportsContext,它也在上下文程序集中(Contexts 文件夹)中定义
public class SportsContext : IDbContext
{
private readonly DbContext _context;
public SportsContext()
{
_context = new DbContext("SportsContext");
}
public void Dispose()
{
_context.Dispose();
}
public IDbSet<T> GetEntitySet<T>() where T : class
{
return _context.Set<T>();
}
public void ChangeState<T>(T entity, EntityState state) where T : class
{
_context.Entry(entity).State = state;
}
public void SaveChanges()
{
_context.SaveChanges();
}
}
这实现了在 Interfaces 程序集中定义的 IDbContext
public interface IDbContext : IDisposable
{
IDbSet<T> GetEntitySet<T>() where T : class;
void ChangeState<T>(T entity, EntityState state) where T : class;
void SaveChanges();
}
在我的 UnitsOfWork 程序集中,我有以下课程
public class SportUnitOfWork : IUnitofWork
{
private readonly IDbContext _context;
public SportUnitOfWork()
{
_context = new SportsContext();
}
private GenericRepository<Team> _teamRepository;
private GenericRepository<Fixture> _fixtureRepository;
public GenericRepository<Team> TeamRepository
{
get { return _teamRepository ?? (_teamRepository = new GenericRepository<Team>(_context)); }
}
public GenericRepository<Fixture> FixtureRepository
{
get { return _fixtureRepository ?? (_fixtureRepository = new GenericRepository<Fixture>(_context)); }
}
public void Save()
{
_context.SaveChanges();
}
public IDbContext Context
{
get { return _context; }
}
private bool _disposed;
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_context.Dispose();
}
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
例如,我在 Repositories 程序集中添加了 GenericRepository 类
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private IDbContext _context;
public GenericRepository(IDbContext context)
{
_context = context;
}
public GenericRepository(IUnitofWork uow)
{
_context = uow.Context;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposing) return;
if (_context == null) return;
_context.Dispose();
_context = null;
}
public void Add(T entity)
{
_context.GetEntitySet<T>().Add(entity);
}
public void Update(T entity)
{
_context.ChangeState(entity, EntityState.Modified);
}
public void Remove(T entity)
{
_context.ChangeState(entity, EntityState.Deleted);
}
public T FindSingle(Expression<Func<T, bool>> predicate = null, params Expression<Func<T, object>>[] includes)
{
var set = FindIncluding(includes);
return (predicate == null) ? set.FirstOrDefault() : set.FirstOrDefault(predicate);
}
public IQueryable<T> Find(Expression<Func<T, bool>> predicate = null, params Expression<Func<T, object>>[] includes)
{
var set = FindIncluding(includes);
return (predicate == null) ? set : set.Where(predicate);
}
public IQueryable<T> FindIncluding(params Expression<Func<T, object>>[] includeProperties)
{
var set = _context.GetEntitySet<T>();
if (includeProperties != null)
{
foreach (var include in includeProperties)
{
set.Include(include);
}
}
return set.AsQueryable();
}
public int Count(Expression<Func<T, bool>> predicate = null)
{
var set = _context.GetEntitySet<T>();
return (predicate == null) ? set.Count() : set.Count(predicate);
}
public bool Exist(Expression<Func<T, bool>> predicate = null)
{
var set = _context.GetEntitySet<T>();
return (predicate == null) ? set.Any() : set.Any(predicate);
}
}
我遇到的问题是从 DbMigrationsConfiguration 继承的 Configuration 类需要一个 DbContext 参数。
错误是错误 1 类型“Contexts.Context.SportsContext”不能用作泛型类型或方法“System.Data.Entity.Migrations.DbMigrationsConfiguration”中的类型参数“TContext”。没有从“Contexts.Context.SportsContext”到“System.Data.Entity.DbContext”的隐式引用转换。
我可以将 SportsContext 更改为也从 DbContext 继承,但随后我需要在 UnitsOfWork 程序集中添加对 EntityFramework 5 的引用,因为我们希望在不引用底层模型的情况下更改或取出每一层,这就是我采用这种模式的原因.
由于我们正在考虑在未来添加更多的上下文和模型,因此希望建立一个架构,我们可以只添加上下文、模型,然后在需要时实现相关接口。
如果我正确理解了模式,WebAPI Restful Web 服务将通过 SportUnitOfWork 与我们的数据进行交互。
如果有人对我如何做到这一点或任何我做错的事情有任何想法,请告诉我
提前谢谢马克