私は Entity Framework の初心者で、同じタイトルの質問を見てきましたが、まだ満足のいく答えが見つかりません。
これが私のクラスです:
public class MyUser
{
public string FirstName { get; set; }
public virtual ICollection<ProfileSkillEdu> Skills { get; set; }
}
そして、コントローラーには次のものがあります。
[HttpPost]
public ActionResult EditProfile(MyUser user, string emailAddress)
{
try
{
if (ModelState.IsValid)
{
_unitOfWork.GetMyUserRepository().Update(user);
_unitOfWork.Save();
return View(user);
}
}
catch (DataException)
{
//Log the error
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
return View(user);
}
私のユーザーリポジトリでは:
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
同じキーを持つオブジェクトが ObjectStateManager に既に存在します。ObjectStateManager は、同じキーを持つ複数のオブジェクトを追跡できません。dbSet.Attach (entityToUpdate) で。変数を調べたところ、MyUser にスキル オブジェクトが 1 つしかない場合は問題ないことがわかりました。これは、アタッチ時にキーが一意であるためです (値は 0)。ただし、MyUser に 2 つのスキル オブジェクトがある場合、両方のプライマリ キーの値が 0 であるため、エラーが発生します。
すべての Skill オブジェクトの主キーの値が 0 である理由を誰か説明できますか? また、この問題に対する簡単な解決策はありますか? 簡単にできるはずだと思っていましたが、これに何時間も苦労してきました。
編集:
問題は文脈の使い方にあるのだろうか。
コントローラーの定義には次のものがあります。
public class MyAccountController : Controller
{
IUnitOfWork _unitOfWork;
public ActionResult EditProfile()
{
if (_user == null)
{
MembershipUser currentUser = Membership.GetUser();
if (currentUser == null)
{
return RedirectToAction("Logon", "Account");
}
Guid currentUserId = (Guid)currentUser.ProviderUserKey;
MyUserService svc = new MyUserService();
MyUser user = svc.GetUserLoaded(currentUserId); //this uses include/eager loading to get the Skills too.
if (user == null)
{
return RedirectToAction("Logon", "Account");
}
else
_user = user;
}
return View(_user);
}
}
私の UnitOfWork には次のものがあります。
public class UnitOfWork:IUnitOfWork
{
private GlobalContext context = new GlobalContext();
private GenericRepository<MyUser> myUserRepository;
private GenericRepository<Skill> skillRepository;
.. and implementation of Save() and Dispose()
}