我使用数据库优先方法在VS.NET 2012中使用Entity Framework 5。我还尝试实现标准的通用存储库接口以及工作单元,以确保所有更新都在单个上下文中发生。创建存储库,UoW,使用DI注入它实际上 我知道如何完成的部分。
我遇到的问题是了解它与下面的MyModel.Context.cs
类如何相关,该类是从Entity Framework 5 T4 POCO模板自动生成的:
public partial class AdventureWorks2008R2Entities : DbContext
{
public AdventureWorks2008R2Entities() : base("name=AdventureWorks2008R2Entities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<Person> People { get; set; }
public DbSet<PersonPhone> PersonPhones { get; set; }
public DbSet<PhoneNumberType> PhoneNumberTypes { get; set; }
}
我认为将要发生的事情是,这个类的一个实例将被发送到我的UoW类的构造函数,如下所示:
public UnitOfWork(IContext context)
{
_context = context;
}
所以我的主要问题是,自动生成的上下文类和我创建的存储库(使用UoW)应该如何协同工作。我在EF4中首先使用代码找到了一些示例,但对于使用POCO生成和存储库模式的Database First方法,EF5没有任何示例。如果有人知道这方面的好例子,请分享。
感谢您提供帮助以解决此问题,谢谢!
答案 0 :(得分:1)
好的,我想出了一个解决这个问题的方法。要开始此方法实际上可以用于Database 1st或Code 1st方法,因为Context不会被修改,只使用它的一个实例。
某些示例将IUnitOfWork接口直接应用于自动生成的AdventureWorks2008R2Entities
类。但是你不想这样做,因为修改可能被覆盖的自动生成的代码并不是一个好主意。
我们的想法是让通用存储库(或者如果不使用通用存储库,每个存储库)接收EF Context的实例,如下所示:
public GenericRepository(DbContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
现在,IUnitOfWork接口应声明EF的方法和每个存储库类型的实例,如下所示:
public interface IUnitOfWork : IDisposable
{
GenericRepository<Person> PersonRepository { get; }
GenericRepository<PersonPhone> PersonPhoneRepository { get; }
void Save();
}
如果尚未实例化,则实现将新建一个存储库实例:
public class UnitOfWork:IUnitOfWork { private DbContext _context; private GenericRepository _personRepository; private GenericRepository _personPhoneRepository;
public UnitOfWork(DbContext context)
{
_context = context;
}
public GenericRepository<Person> PersonRepository
{
get
{
if (this._personRepository == null)
{
this._personRepository = new GenericRepository<Person>(_context);
}
return _personRepository;
}
}
public GenericRepository<PersonPhone> PersonPhoneRepository
{
get
{
if (this._personPhoneRepository == null)
{
this._personPhoneRepository = new GenericRepository<PersonPhone>(_context);
}
return _personPhoneRepository;
}
}
public void Save()
{
try
{
_context.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
}
}
#region Implementation of IDisposable
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Disposes off the managed and unmanaged resources used.
/// </summary>
/// <param name="disposing"></param>
private void Dispose(bool disposing)
{
if (!disposing)
return;
if (_disposed)
return;
_disposed = true;
}
private bool _disposed;
#endregion
}
最后,要使用您的存储库的工作单元实例,您可以通过它到达相应的存储库实例,并且UoW将负责确保所有更改都发生在上相同的上下文:
_unitOfWork.PersonRepository.Insert(person);
_unitOfWork.Save();
答案 1 :(得分:0)