1

以下のリポジトリパターンを使用しています。この例外を取得するクラスからインスタンスを作成すると、次のようになります。

 public interface IRepository<TEntity> : IDisposable where TEntity : class
{
    IQueryable<TEntity> GetQuery();
    IEnumerable<TEntity> GetAll();
    IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
    TEntity Single(Expression<Func<TEntity, bool>> predicate);
    TEntity First(Expression<Func<TEntity, bool>> predicate);
    void Add(TEntity entity);
    void Delete(TEntity entity);
    void Attach(TEntity entity);
    void SaveChanges();
    void SaveChanges(SaveOptions options);
}

public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
    private ObjectContext _context;
    private IObjectSet<TEntity> _objectSet;

    public GenericRepository(ObjectContext context)
    {
        _context = context;
        _objectSet = _context.CreateObjectSet<TEntity>();
    }

    public IQueryable<TEntity> GetQuery()
    {
        return _objectSet;
    }

    public IEnumerable<TEntity> GetAll()
    {
        return GetQuery().AsEnumerable();
    }

    public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
    {
        return _objectSet.Where<TEntity>(predicate);
    }

    public TEntity Single(Expression<Func<TEntity, bool>> predicate)
    {
        return _objectSet.Single<TEntity>(predicate);
    }

    public TEntity First(Expression<Func<TEntity, bool>> predicate)
    {
        return _objectSet.First<TEntity>(predicate);
    }

    public void Delete(TEntity entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException("entity");
        }

        _objectSet.DeleteObject(entity);
    }

    public void Add(TEntity entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException("entity");
        }

        _objectSet.AddObject(entity);
    }

    public void Attach(TEntity entity)
    {
        _objectSet.Attach(entity);
    }

    public void SaveChanges()
    {
        _context.SaveChanges();
    }

    public void SaveChanges(SaveOptions options)
    {
        _context.SaveChanges(options);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing && _context != null)
        {
            _context.Dispose();
            _context = null;
        }
    }
}

使用:

 var db = new AdventureWorks2012Entities();  
 IRepository<Person> person = new GenericRepository<Person>();

例外: ここに画像の説明を入力してください

ここに画像の説明を入力してください

4

3 に答える 3

2

DbContext問題は、ラッパーが含まれているEntityFramework4.1以降を使用していることですObjectContext。ただし、リポジトリは引き続きを使用しObjectContextます。次を受け入れる別のコンストラクターを追加しますDbContext

public GenericRepository(DbContext context)
{
    _context = (context as IObjectContextAdapter).ObjectContext;
    _objectSet = _context.CreateObjectSet<TEntity>();
}

ObjectContextインターフェイスにキャストDbContextすることで、ラップされたインスタンスを取得できIObjectContextAdapterます。もう1つのオプションは、最新のを使用するようにリポジトリクラスを更新するDbContextことですが、これには、コンストラクタを1つ追加するよりも、少し多くのコーディングが必要になります。

public class GenericRepository<TEntity> : IRepository<TEntity> 
   where TEntity : class
{
    private DbContext _context; // instead of ObjectContext
    private DbSet<TEntity> _set; // instead of IObjectSet<TEntity>

    public GenericRepository(DbContext context)
    {
        _context = context;
        _set = _context.Set<TEntity>();
    }

    public IQueryable<TEntity> GetQuery()
    {
        return _set;
    }

    public IEnumerable<TEntity> GetAll()
    {
        return GetQuery().AsEnumerable();
    }

    public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
    {
        return _set.Where<TEntity>(predicate);
    }    

    // etc
}
于 2013-02-11T12:19:05.260 に答える
0

これはすべてエラーメッセージにあります。最初のメッセージは十分に単純です。リポジトリはパラメータ(指定しない)を予期してObjectContextいます。

2つ目は、基本的に、dbインスタンスがタイプではないObjectContextか、少なくともその特定のタイプにダウンキャストできないことを示しています。あなたの確か AdventureWorks2012Entitiesがそれから派生しているなら、あなたObjectContextは直接キャストをすることができます例えば

IRepository<Person> repo = new GenericRepository<Person>((ObjectContext)db);
于 2013-02-11T12:21:11.870 に答える
0

DbSetをリポジトリに渡すことができるので、次のようになります。

var db = new AdventureWorks2012Entities();
IRepository<Person> person = new GenericRepository<Person>(db.Person);

ここで、db.PersonはAdventureWorks2012EntitiesDbContextクラスで宣言されています。

私はUnitOfWork/Repository抽象化レイヤーを開発して、NHibernate / EntityFramework / Ravenなどから簡単に切り替えて、テストをより適切に行えるようにしています。

ここにソースコードがあり、ここにNugetパッケージがあります。特に、DDD方法論をより適切にサポートするために、コードベースを変更する必要があります。

  1. 作業単位を削除します。1回に1つの集計で作業するため、必要ありません。
  2. Commitメソッドをリポジトリに追加します
于 2013-02-11T12:24:01.720 に答える