は私がしたい2つの理由 Entity Frameworkでリポジトリのトランザクションを実装するにはどうすればよいですか?
- のための私のアプリケーションでのリポジトリの設計パターンデカップル私はいくつかの点
- でEntity Frameworkのを使用しないことを決定する場合におけるエンティティから自分のアプリケーションを利用しようとしています
は私がモデル
I成功裏のセットアップと相互作用して、リポジトリのパターンを使用するロジックができ、再利用になりたいです。しかし、私はトランザクションに対処するために1つの複雑さを持っています。
私はリポジトリへの複数の呼び出しを行い、コミットまたはロールバックできるようにトランザクションを使用できるようにします。ここで
その後、私は今、とても
using Support.Repositories.Contracts;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
namespace Support.Repositories
{
public class EntityRepository<TEntity> : IRepository<TEntity>
where TEntity : class
{
protected readonly DbContext Context;
protected readonly DbSet<TEntity> DbSet;
public EntityRepository(DbContext context)
{
Context = context;
DbSet = context.Set<TEntity>();
}
public TEntity Get(int id)
{
return DbSet.Find(id);
}
public IEnumerable<TEntity> GetAll()
{
return DbSet.ToList();
}
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return DbSet.Where(predicate);
}
public TEntity SingleOrDefault(Expression<Func<TEntity, bool>> predicate)
{
return DbSet.SingleOrDefault(predicate);
}
public void Add(TEntity entity)
{
DbSet.Add(entity);
}
public void AddRange(IEnumerable<TEntity> entities)
{
DbSet.AddRange(entities);
}
public void Remove(TEntity entity)
{
DbSet.Remove(entity);
}
public void RemoveRange(IEnumerable<TEntity> entities)
{
DbSet.RemoveRange(entities);
}
}
}
のようにEntity Frameworkのための実装を作成し、私のリポジトリインターフェースは
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Support.Repositories.Contracts
{
public interface IRepository<TModel> where TModel : class
{
// Get records by it's primary key
TModel Get(int id);
// Get all records
IEnumerable<TModel> GetAll();
// Get all records matching a lambda expression
IEnumerable<TModel> Find(Expression<Func<TModel, bool>> predicate);
// Get the a single matching record or null
TModel SingleOrDefault(Expression<Func<TModel, bool>> predicate);
// Add single record
void Add(TModel entity);
// Add multiple records
void AddRange(IEnumerable<TModel> entities);
// Remove records
void Remove(TModel entity);
// remove multiple records
void RemoveRange(IEnumerable<TModel> entities);
}
}
ですが、私はそう
using System;
namespace App.Repositories.Contracts
{
public interface IUnitOfWork : IDisposable
{
IUserRepository Users { get; }
IAddressRepository Addresses { get; }
}
}
のようなリポジトリと対話するための
IUnitOfWork
を作成
次に、このインターフェイスをEntity Framework liに実装しましたこのKE:
using App.Contexts;
using App.Repositories.Contracts;
using App.Repositories.Entity;
namespace App.Repositories
{
public class UnitOfWork : IUnitOfWork
{
private readonly AppContext _context;
public IUserRepository Users { get; private set; }
public IAddressRepository Addresses { get; private set; }
public UnitOfWork(AppContext context)
{
_context = context;
Users = new UserRepository(_context);
Addresses = new AddressRepository(_context);
}
public UnitOfWork() : this(new AppContext())
{
}
public int Save()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
}
私は今、この
using(var repository = new UnitOfWork())
{
repository.Users.Add(new User(... User One ...))
repository.Save();
repository.Addresses(new Address(... Address For User One ...))
repository.Save();
repository.Users.Add(new User(... User Two...))
repository.Save();
repository.Addresses(new Address(... Address For User Two...))
repository.Save();
}
のようなリポジトリを使用することができるよ、私はすべてが良い場合にのみ、その後、ロールバックそれ以外の場合はコミットして、データベースのトランザクションを使用できるようにしたいです。
私の最初の取り組みは、UnitOfWork
クラスにBeginTransaction()
という新しいメソッドを追加することです。しかし、私のコードをEntity Frameworkにのみ結合します。
ここでは、BeginTransaction()
,Commit()
、Rollback()
メソッドを提供する新しいインターフェイスを作成して、任意のORMの実装を書くことを考えています。
すなわち
namespace Support.Contracts
{
public IRepositoryDatabase
{
SomethingToReturn BeginTransaction();
void Commit();
void Rollback();
}
}
質問は、私が正しく実装することができますので、私は戻って私のUnitOfWorkにIRepositoryDatabase
を結ぶだろうかありますか? BeginTransaction()
は何を返す必要がありますか?
EFは、(デフォルトの保存上のすべての変更されたエンティティまたはnoneで保存されます)コールからUnitOfWorkの実装を消費する方法であります。 –
ですが、どのようにトランザクションを開始しますか? –
エンティティを10個変更し、その後Save()を呼び出します。 EFによって1つのトランザクションに書き込まれます(エラーが発生した場合は何も書き込まれません)。 –