多くのリソースから EF5 Code First を使用して Generic Repository、Unit of Work パターンを実装しており、次のアセンブリを作成しました。
インターフェイス、コンテキスト、モデル、リポジトリ、UnitsOfWork
Context アセンブリには、Configuration.cs を含む migrations フォルダーがあります。
internal sealed class Configuration : DbMigrationsConfiguration<Context.SportsContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(Context.SportsContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
ご覧のとおり、この DbMigrationsConfiguration は、コンテキスト アセンブリ (Contexts フォルダー) でも定義されている SportsContext を取り込みます。
public class SportsContext : IDbContext
{
private readonly DbContext _context;
public SportsContext()
{
_context = new DbContext("SportsContext");
}
public void Dispose()
{
_context.Dispose();
}
public IDbSet<T> GetEntitySet<T>() where T : class
{
return _context.Set<T>();
}
public void ChangeState<T>(T entity, EntityState state) where T : class
{
_context.Entry(entity).State = state;
}
public void SaveChanges()
{
_context.SaveChanges();
}
}
これは、Interfaces アセンブリで定義されている IDbContext を実装します。
public interface IDbContext : IDisposable
{
IDbSet<T> GetEntitySet<T>() where T : class;
void ChangeState<T>(T entity, EntityState state) where T : class;
void SaveChanges();
}
私の UnitsOfWork アセンブリには、次のクラスがあります
public class SportUnitOfWork : IUnitofWork
{
private readonly IDbContext _context;
public SportUnitOfWork()
{
_context = new SportsContext();
}
private GenericRepository<Team> _teamRepository;
private GenericRepository<Fixture> _fixtureRepository;
public GenericRepository<Team> TeamRepository
{
get { return _teamRepository ?? (_teamRepository = new GenericRepository<Team>(_context)); }
}
public GenericRepository<Fixture> FixtureRepository
{
get { return _fixtureRepository ?? (_fixtureRepository = new GenericRepository<Fixture>(_context)); }
}
public void Save()
{
_context.SaveChanges();
}
public IDbContext Context
{
get { return _context; }
}
private bool _disposed;
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_context.Dispose();
}
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
例として、Repositories アセンブリに GenericRepository クラスを追加しました。
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
private IDbContext _context;
public GenericRepository(IDbContext context)
{
_context = context;
}
public GenericRepository(IUnitofWork uow)
{
_context = uow.Context;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposing) return;
if (_context == null) return;
_context.Dispose();
_context = null;
}
public void Add(T entity)
{
_context.GetEntitySet<T>().Add(entity);
}
public void Update(T entity)
{
_context.ChangeState(entity, EntityState.Modified);
}
public void Remove(T entity)
{
_context.ChangeState(entity, EntityState.Deleted);
}
public T FindSingle(Expression<Func<T, bool>> predicate = null, params Expression<Func<T, object>>[] includes)
{
var set = FindIncluding(includes);
return (predicate == null) ? set.FirstOrDefault() : set.FirstOrDefault(predicate);
}
public IQueryable<T> Find(Expression<Func<T, bool>> predicate = null, params Expression<Func<T, object>>[] includes)
{
var set = FindIncluding(includes);
return (predicate == null) ? set : set.Where(predicate);
}
public IQueryable<T> FindIncluding(params Expression<Func<T, object>>[] includeProperties)
{
var set = _context.GetEntitySet<T>();
if (includeProperties != null)
{
foreach (var include in includeProperties)
{
set.Include(include);
}
}
return set.AsQueryable();
}
public int Count(Expression<Func<T, bool>> predicate = null)
{
var set = _context.GetEntitySet<T>();
return (predicate == null) ? set.Count() : set.Count(predicate);
}
public bool Exist(Expression<Func<T, bool>> predicate = null)
{
var set = _context.GetEntitySet<T>();
return (predicate == null) ? set.Any() : set.Any(predicate);
}
}
私が抱えている問題は、DbMigrationsConfiguration から継承する Configuration クラスが DbContext パラメータを期待していることです。
エラーはエラー 1 型 'Contexts.Context.SportsContext' は、ジェネリック型またはメソッド 'System.Data.Entity.Migrations.DbMigrationsConfiguration' の型パラメーター 'TContext' として使用できません。「Contexts.Context.SportsContext」から「System.Data.Entity.DbContext」への暗黙的な参照変換はありません。
SportsContext を変更して DbContext から継承することもできますが、UnitsOfWork アセンブリに EntityFramework 5 への参照を追加する必要があります。これは、基になるモデルへの参照なしで各レイヤーを変更または削除する可能性があるためです。これが、このパターンを使用した理由です。 .
将来的にさらにコンテキストとモデルを追加することを検討しているため、必要に応じてコンテキスト、モデルを追加し、関連するインターフェースを実装できるようにアーキテクチャをセットアップしたいと考えました。
パターンを正しく理解していれば、WebAPI Restful Web サービスは SportUnitOfWork を介してデータと対話します。
どうすればこれを行うことができるか、または私が間違っていることについて誰かがアイデアを持っている場合は、私に知らせてください
前もって感謝します マーク