web-dev-qa-db-ja.com

Entity Framework 6でリポジトリパターンを使用してレコードを更新する

シンプルなブログアプリケーションを作成し、汎用リポジトリパターンでCRUD操作を確立しようとしていますが、更新メソッドで次のようなエラーが表示されます。

「System.Data.Entity.DbSet」には「Entry」の定義が含まれておらず、タイプ「System.Data.Entity.DbSet」の最初の引数を受け入れる拡張メソッド「Entry」が見つかりません(usingディレクティブがありませんか?またはアセンブリ参照?)

説明された投稿 DbContextに間接レベルを追加してEntry()を「偽造」する方法に従いました。ただし、MVC 5では、DbContextではなく、IdentityDbContextを継承しています。著者の修正を実装してみましたが、エラーは続きます。

私の質問

IdentityDbContextを使用してEntity Framework 6のリポジトリに更新メソッドを追加するにはどうすればよいですか?この方法で行う必要がない場合、このパターンでレコードを更新するにはどうすればよいですか?

他のすべてのメソッドは期待どおりに機能することに注意してください。

私の汎用リポジトリ:

public class BlogEngineRepository<T> : IRepository<T> where T : class
    {
        protected DbSet<T> DbSet;

        public BlogEngineRepository(DbContext dataContext)
        {
            DbSet = dataContext.Set<T>();
        }

        #region IRepository<T> Members

        public void Insert(T entity)
        {
            DbSet.Add(entity);
        }

        public void Delete(T entity)
        {
            DbSet.Remove(entity);
        }

        public void Update(T entity)
        { 

           DbSet.Entry(entity).State = System.Data.Entity.EntityState.Modified;

        }

        public IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate)
        {
            return DbSet.Where(predicate);
        }

        public IQueryable<T> GetAll()
        {
            return DbSet;
        }

        public T GetById(int id)
        {
            return DbSet.Find(id);
        }

        #endregion
    }
16
Dan Beaulieu

更新は次のようになります( Dan Beaulieuの答えを拡大 ):

[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Edit([Bind(Include = "Id,Title,IntroText,Body,Modified,Author")] Post post)
{
    using (UnitOfWork uwork = new UnitOfWork())
    {
        post.Modified = DateTime.Now;
        uwork.PostRepository.Update(post);

        uwork.Commit();

        return RedirectToAction("Index");
    }
}

RepositoryPatternは次のようになります:

public class BlogEngineRepository<T> : IRepository<T> where T : class
{
  public BlogEngineRepository(DbContext dataContext)
  {
    DbSet = dataContext.Set<T>();
    Context = dataContext;
  }

  public T Update(T entity)
  {
     DbSet.Attach(entity);
     var entry = Context.Entry(entity);
     entry.State = System.Data.EntityState.Modified;
  }
}

エンティティのリストを更新する効率的な方法 の答えの完全な説明を表示して、更新の詳細の詳細を確認できます。

14
Erik Philips

わかりました、私はこれを理解しました。新しいリポジトリパターン(Entity Framework 6)にUpdateメソッドが存在しない理由は、必要ない =。 IDでレコードを取得し、変更を加えてからコミット/保存します。

たとえば、これは私の編集POST postControllerのメソッド:

[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Edit([Bind(Include = "Id,Title,IntroText,Body,Modified,Author")] Post post)
{
    using (UnitOfWork uwork = new UnitOfWork())
    {
        Post edit = uwork.PostRepository.GetById(post.Id);
        edit.Title = post.Title;
        edit.IntroText = post.IntroText;
        edit.Body = post.Body;
        edit.Modified = DateTime.Now;

        uwork.Commit();

        return RedirectToAction("Index");
    }
}

RepositoryPatternは次のようになります:

public class BlogEngineRepository<T> : IRepository<T> where T : class
{
    protected DbSet<T> DbSet;

    public BlogEngineRepository(DbContext dataContext)
    {
        DbSet = dataContext.Set<T>();
    } 

    public void Insert(T entity)
    {
        DbSet.Add(entity);
    }

    public void Delete(T entity)
    {
        DbSet.Remove(entity); 
    }

    public IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate)
    {
        return DbSet.Where(predicate);
    }

    public IQueryable<T> GetAll()
    {
        return DbSet;
    }

    public T GetById(int id)
    {
        return DbSet.Find(id);
    } 
}
19
Dan Beaulieu