【问题标题】:How to use generated context class from EF5 and Database First with Repository and UoW如何将 EF5 和 Database First 生成的上下文类与 Repository 和 UoW 一起使用
【发布时间】:2013-01-17 19:18:27
【问题描述】:

我在 VS.NET 2012 中使用 Database First 方法使用 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 却没有。如果有人知道这方面的一个很好的例子,请分享。

感谢您帮助解决此问题,谢谢!

【问题讨论】:

    标签: entity-framework repository-pattern


    【解决方案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 { 私有 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();
    

    【讨论】:

      【解决方案2】:
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-21
      相关资源
      最近更新 更多