3

このような質問がすでにたくさん寄せられていることは承知していますが、何が悪いのか理解できないようです。これは私のコードです:

[HttpGet]
public ViewResult Edit(int id)
{
    User user = userRepository.GetAll().FirstOrDefault(x => x.ID == id);

    return View("Edit", user);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(User user)
{
    if (ModelState.IsValid)
    {
        user.Password = HashHelper.GetHash(user.Password);
        if (user.ID == 0) // new user
        {
            User testUser = userRepository.GetAll().FirstOrDefault(x => x.Name.Equals(user.Name));

            if (testUser == null)
                userRepository.AddEntity(user);
            else
            {
                ModelState.AddModelError("", "Deze gebruikersnaam bestaat al");
                return View(user);
            }
        }
        else // edit existing user
        {   
            User tempUser = userRepository.GetAll().First(x => x.ID == user.ID);

            if (!user.Name.Equals(tempUser.Name))
            {
                // naam werd aangepast
                int count = userRepository.GetAll().Count(x => x.Name.Equals(user.Name));

                if (count > 0)
                {
                    ModelState.AddModelError("", "Deze gebruikersnaam bestaat al");
                    return View(user);  
                }

            }

            userRepository.UpdateEntity(user);

        }
        userRepository.SaveChanges();
        return RedirectToAction("Index");
    }
    else
    {
        return View(user);
    }
}

UpdateEntity:

public void UpdateEntity(T entity)
{
    var entry = context.Entry(entity);
    if (entry.State == EntityState.Detached)
        context.Set<T>().Attach(entity);

    context.Entry<T>(entity).State = EntityState.Modified;
}

これにより、次のエラーが発生します。

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key

理解できません。なぜこれが機能しないのですか、どうすれば修正できますか?

4

1 に答える 1

2

複数の問題があります。

  • GetAll()データベースに何千ものエンティティがある場合は、単一のエンティティをフェッチする場合は呼び出さないでください。リポジトリに SingleOrDefault を実装するだけです。

使用する :

User testUser = userRepository.FirstOrDefault(x => x.Name.Equals(user.Name));

それ以外の :

User testUser = userRepository.GetAll().FirstOrDefault(x => x.Name.Equals(user.Name));
  • データベースから既存のユーザーをフェッチした後、ページから返された値を保持しようとするのではなく、新しい値を使用してこの項目を更新するだけです。

使用する

User tempUser = userRepository.GetAll().First(x => x.ID == user.ID);
tempUser.UserName = user.UserName;
....
SaveChanges();

ページから取得したユーザーを永続化しようとする代わりに。

  • エンティティのキ​​ーを決定する必要があります。それは名前ですか、それはIDですか、それとも両方ですか。
于 2013-02-13T08:47:37.077 に答える