2

Database Firstアプローチを使用して、VS.NET 2012 で Entity Framework 5 を使用しています。また、すべての更新が単一のコンテキストで確実に行われるように、Unit of Work とともに標準の汎用リポジトリ インターフェイスを実装しようとしています。リポジトリ、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 生成とリポジトリ パターンを使用したデータベース ファースト アプローチを使用する EF5 では何も見つかりませんでした。誰かがこれに関する良い例を知っているなら、共有してください。

これを解決するための助けをいただければ幸いです、ありがとう!

4

2 に答える 2

1

わかりました、この問題を解決する方法を 1 つ考え出しました。コンテキストは変更されず、そのインスタンスのみが使用されるため、このメソッドを開始するには、データベース ファーストまたはコード ファーストのアプローチで実際に機能する可能性があります。

AdventureWorks2008R2Entities一部のサンプルでは、​​IUnitOfWork インターフェイスが自動生成クラスに直接適用されています。ただし、上書きされる可能性のある自動生成されたコードを変更することは良い考えではないため、これを行うことは望ましくありません。

アイデアは、汎用リポジトリ (または、汎用リポジトリを使用しない場合は、個々のリポジトリごと) に、以下のような 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();
}

以下のように、まだインスタンス化されていない場合、実装はリポジトリのインスタンスを新しく作成します。

public class 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

}

最後に、Unit of Work インスタンスをリポジトリに使用するには、それを介して適切なリポジトリ インスタンスにアクセスします。UoW は、保存されたすべての変更が同じコンテキストで発生するようにします。

_unitOfWork.PersonRepository.Insert(person);
_unitOfWork.Save();
于 2013-01-21T14:53:48.693 に答える