3

これを行うには、データ アクセス レイヤーでリポジトリと UnitOfwork を使用します。

 public interface IAggregateRoot
    {
    }

これは私の汎用リポジトリインターフェースです:

 public interface IRepository<T>
        {
            IEnumerable<T> GetAll();
            T FindBy(params Object[] keyValues);
            void Add(T entity);
            void Update(T entity);
            void Delete(T entity);

        }

モデルのPOCO Contactクラス

 public class Contact :IAggregateRoot
        {
            public Guid Id { get; set; }
            public string Name { get; set; }
            public string Email { get; set; }
            public string Title { get; set; }
            public string Body { get; set; }
            public DateTime CreationTime { get; set; }
        }

そして、これは IRepository から継承し、おそらくそれが独自のメソッドである私の IContactRepository

 public interface IContactRepository : IRepository<Contact>
        {
        }

今、私はこのように IUitOfWork と UnitOfwork でやった

public interface IUnitOfWork 
    {
        IRepository<Contact> ContactRepository { get; }
    }

public class UnitOfWork : IUnitOfWork
    {
        private readonly StatosContext _statosContext = new StatosContext();
        private IRepository<Contact> _contactUsRepository;

 public IRepository<Contact> ContactRepository
        {
            get { return _contactUsRepository ?? (_contactUsRepository = new Repository<Contact>(_statosContext)); }
        }
}

私のリポジトリについても

public class Repository<T> : IRepository<T> where T : class, IAggregateRoot
    {
       //implementing methods 
    }

Service で UnitOfwork を使用してリポジトリにアクセスすることで、すべての CRUD 操作を実行できます。例:

_unitOfWork.ContactRepository.Add(contact);
            _unitOfWork.SaveChanges();

しかし、私はこのようにしたい

_

ContactRepository.Add(contact);
            _unitOfWork.SaveChanges();

(_unitOfWork.ContactRepository による _ContactRepository No による CRUD と汎用メソッドの取得) ContactRepository メソッドをいくつかの特定のクエリに取得したいので、誰か助けてください??

4

3 に答える 3

11

あなたの質問に対する直接的な回答ではありませんが、物事を少し単純化し、重複を減らすことができます。

たとえば EntityFramework Power Tools を使用して Code First をリバース エンジニアリングする (または単に Code First を一般的に使用する) 場合DbContext、UoW とリポジトリとして機能するクラスが 1 つになります。たとえば、次のようになります。

public partial class YourDbContext : DbContext
{
    public DbSet<Contact> Contacts {get; set;}
}

物事をテスト可能にしたい場合は、簡単な方法があります: 非常に薄いインターフェースを導入します:

public interface IDbContext
{
    IDbSet<T> EntitySet<T>() where T : class;
    int SaveChanges();
    //you can reveal more methods from the original DbContext, like `GetValidationErrors` method or whatever you really need.
}

次に、部分クラスの 2 番目の部分で別のファイルを作成します。

public partial class YourDbContext : IDbContext
{
     public IDbSet<T> EntitySet<T>() where T : class
     {
         return Set<T>();
     }
}

タダ!IDbContextこれで、YourDbContextバックアップして注入できます。

//context is an injected IDbContext:
var contact = context.EntitySet<Contact>().Single(x => x.Id == 2);    
contact.Name = "Updated name";
context.EntitySet<Contact>().Add(new Contact { Name = "Brand new" });
context.SaveChanges();

コンテキストの破棄を制御したい場合は、独自の ( Gasp ) IDbContextFactory(必要なものに応じてジェネリックかどうか) を記述し、代わりにそのファクトリを注入する必要があります。

独自FindAddUpdateメソッドを記述する必要はありません。適切に処理されるようになりました。明示的なトランザクションを導入する方が簡単で、すべてがインターフェイス ( 、 )DbContextの背後にうまく隠されています。IDbContextIDbSet

ちなみに、 はNHibernate のand -とIDbContextFactory同等です。EFもこれをすぐに使えるといいのですが。ISessionFactoryIDbContextISession

于 2013-05-09T18:04:09.833 に答える
0

UnitOfWork クラス内で、DBContext または ObjectContext を実装する必要があります。

UnitOfWork は、システムに関係なく、すべてのトランザクションを分離します。EFはDB接続専用です。システムが DB のみを使用している場合でも、将来の拡張のために別の UnitOfWork クラスを保持することをお勧めします。

また、作業単位 Commit() 内で、内部的に実装された DBContext.SaveChanges() を呼び出すことができます。

この DBcontext は、unitofwork 内で宣言されたすべてのリポジトリにアクセスできます。したがって、リポジトリはDBcontextに追加または削除し、unitOfworkはそれをコミットします。

Cloud Blob、テーブル ストレージなど、さまざまなストレージにまたがるシナリオがある場合、EF コンテキストを実装したのと同じように、UnitofWork 内にそれらを実装できます。また、一部のリポジトリは、Table Storage と一部の EF コンテキストにアクセスできます。

ヒント: DBContext の代わりに ObjectContext を実装すると、キャッシュ シナリオで有利になります。また、フレームワークを拡張するためのオプションが増えました。

于 2014-08-04T10:38:46.370 に答える