1

私は汎用リポジトリを持っています:

    public class GenericRepository<TEntity> : AbstractRepository<TEntity>, IRepository<TEntity> where TEntity : class
    {
        private DbContext _context;
        [...]
        public GenericRepository(DbContext context)
        {
            _context = context;
            context.Configuration.AutoDetectChangesEnabled = true;
            _dbSet = _context.Set<TEntity>();
        }
        [...]
        public void SaveChanges()
        {
            _context.SaveChanges();
        }
        [...]
    public void Add(TEntity entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException("entity");
        }

        _dbSet.Add(entity);
    }
        [...]
    public virtual void Update(TEntity entity)
    {
        _context.Entry(entity).State = EntityState.Modified;
    }

私のコントローラーには、次のコードがあります。

    [HttpPost]
    public ActionResult Edit(Project project)
    {
          if (ModelState.IsValid)
        {
            if (project.Id == 0)
            {
                ProjectRepository.Add(project);
            }
            else
            {
                ProjectRepository.Update(project);
            }

            ProjectRepository.SaveChanges();
            [...]

選択と挿入は正常に機能しますが、更新は機能しません: InvalidOperationException が発生します (ドイツ語のエラー メッセージの英語訳は、「オブジェクト ステート マネージャーに同じキーを持つオブジェクトが既に存在します。オブジェクト ステート マネージャーは、同じキーを持つ複数のオブジェクトを追跡できません。鍵。")。

私は開発マシンの唯一のユーザーであり、別の場所でレコードを変更していないため、それがわかりません。

ここで何が間違っているのか分かりますか?

4

3 に答える 3

6

これらの答えを見てください:

基本的に、これを行う必要があります:

 var entity = _context.Projects.Find(project.ProjectId);
 _context.Entry(entity).CurrentValues.SetValues(project);

うまくいけば、これが役に立ちます。

于 2012-07-25T11:03:06.967 に答える
0

インスタンスは、リポジトリからロードされるのprojectではなく、モデル バインディングによって作成されるため、実際にリポジトリからインスタンスをロードしてprojectから、そのプロパティを変更する必要があります。

于 2012-07-25T11:12:26.290 に答える
0

免責事項: 私は Entity Framework を使用したことがありません。ASP.NET MVC と nHibernate の経験に基づいてこれを書いていますが、同じパターンを適用できるはずです。

まず最初に、実際の問題は二重キーの挿入です。これは、編集アクションに渡されるプロジェクトオブジェクトが、更新しようとしているオブジェクトと同じではないためです (これは、モデルバインダーベースから作成されています) FormValueProvider の値について)。excat は同じ値を持つ可能性があり、そのため同じ ID を持っている可能性がありますが、ORM の場合、DB に永続化されたことのない新しいオブジェクトです。

次のパターンを使用してこれを防ぐことができます (quick'n dirty sample-code)

    [HttpPost]
    public ActionResult Edit(Project project)
    {
        if (ModelState.IsValid)
        {
            if (project.Id == 0)
            {
                ProjectRepository.Add(project);
            }
            else
            {
                Project dbProject = ProjectRepository.GetById(project.Id); //or whatever your method to retrieve entities by Id is named
                UpdateModel(dbProject, "project"); //http://msdn.microsoft.com/en-us/library/dd470933.aspx
                ProjectRepository.Update(project);
            }
        }
    }
于 2012-07-25T13:24:51.393 に答える