2

我使用数据库优先方法在 VS.NET 2012 中使用实体框架 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 却没有。如果有人知道这方面的一个很好的例子,请分享。

感谢您对清除此问题的任何帮助,谢谢!

4

2 回答 2

1

好的,我想出了一种方法来解决这个问题。首先,此方法实际上可以用于 Database 1st 或 Code 1st 方法,因为没有修改 Context 并且只使用了它的一个实例。

一些示例将 IUnitOfWork 接口直接应用于自动生成的AdventureWorks2008R2Entities类。但是,您不希望这样做,因为修改可能被覆盖的自动生成代码并不是一个好主意。

这个想法是让通用存储库(或者如果不使用通用存储库,每个单独的存储库)接受 EF 上下文的实例,如下所示:

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();
}

如果尚未实例化,则该实现将新建一个存储库实例,如下所示:

公共类 UnitOfWork : IUnitOfWork { private DbContext _context; 私有 GenericRepository _personRepository;私有 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();
于 2013-01-21T14:53:48.693 回答