EF codefirst 多对多实体关系,无法保存实体间的关联

时间:2021-12-13 11:58:10
首先感谢各位能够查看我的提问

EF更新实体时,可以对实体对象进行跟踪。

如 方法一
public ActionResult Update(SysAccount account,  string returnUrl)

其中account是表单传递过来的对象,对象里属性包含主键ID。
直接AccountServer.UpdateEntity(account);就可以实现更新。

也可以先根据ID查询出实体,再对实体进行修改。
如 方法二
public ActionResult Update(int ID,  string returnUrl)
{
Account account=GetEntityByID(ID)
account.Name=Request["accountname"];
AccountServer.UpdateEntity(account);
}


主外键一对一和一对多都能够实现跟踪,然后自动绑定外键和关联的模型主键。

但是今天account和role是多对多关系。
下面Update方法的代码account的其他属性都能得到更新,而且没有报错。
只有account.Companies没有更新
断点看了一下account.Companies有值且正确,只是没有保存更新
ISysAccount.UpdateEntity更新方法的主要代码如下
public virtual T UpdateEntity(T entity)
{
if (entity != null)
{
context.Set<T>().Attach(entity);
context.Entry(entity).State = EntityState.Modified;
context.SaveChanges();
}
return entity;
}



现在用的方法二,先查询一次,对查询结果进行修改。相对于方法一,多了一次查询。

之前一对多的跟踪是没问题的,执行DbContext的SaveChange后,导航属性外键会于其对应的实体相关联。
现在多对多的关联关系的修改为什么没有保存。
奇怪的是,AddEntity(account)时,也就是包含多对多关系的实体在创建时,关联的实体关系是能保存的。add主要代码如下

public virtual T AddEntity(T entity)
{
context.Set<T>().Add(entity);
context.SaveChanges();
return entity;
}


采用FluntAPI绑定多对多关系
this.HasMany(u => u.Companies)
.WithMany(u => u.Accounts)
.Map(m =>
{
m.ToTable("AccountCompany");
m.MapLeftKey("AccountId");
m.MapRightKey("CompanyId");
});


下面是更新实体的Update方法

[HttpPost]
public ActionResult Update(SysAccount account, string returnUrl)
{
if (ModelState.IsValid)
{
////添加用户的公司
var companyIds = Request["CompanyId"];
if (!string.IsNullOrEmpty(companyIds))
{
    List<int> companyIdsList = companyIds.Split(',').Select(Int32.Parse).ToList();
    //新的公司
    var companiesList = ISysCompany.LoadEntities(c => c.EnabledMark == true).Where(c => companyIdsList.Contains(c.Id)).ToList();

    foreach (var company in companiesList)
    {
        account.Companies.Add(company);
    }
}
else
{
    account.Companies.Clear();
}

if (ISysAccount.UpdateEntity(account) != null)
{
if (String.IsNullOrEmpty(returnUrl))
return RedirectToAction("List", "Account");
else
return Redirect(returnUrl);
}
else
{
ModelState.AddModelError("", "修改失败");
}
}
else
{
ModelState.AddModelError("", "请填写完整");

}

List<SelectListItem> enabledMark = new List<SelectListItem>() { new SelectListItem() { Value = "0", Text = "删除" }, new SelectListItem() { Value = "1", Text = "正常" } };
ViewBag.EnabledMark = new SelectList(enabledMark, "Value", "Text", account.EnabledMark);

return View(account);
}

4 个解决方案

#1


提问有点仓促,语言组织的有点差,希望大家不要介意。

#2


还是喜欢dbfirst,数据库结构设计的事情让数据库自己来保证,出问题也是dba的事,何况数据库可能还是第三方的

#3


看看增加以下[InverseProperty("")]  属性能否解决这个问题
http://blog.csdn.net/hanjun0612/article/details/52838692

#4


引用 3 楼 hanjun0612 的回复:
看看增加以下[InverseProperty("")]  属性能否解决这个问题
http://blog.csdn.net/hanjun0612/article/details/52838692


多谢!

#1


提问有点仓促,语言组织的有点差,希望大家不要介意。

#2


还是喜欢dbfirst,数据库结构设计的事情让数据库自己来保证,出问题也是dba的事,何况数据库可能还是第三方的

#3


看看增加以下[InverseProperty("")]  属性能否解决这个问题
http://blog.csdn.net/hanjun0612/article/details/52838692

#4


引用 3 楼 hanjun0612 的回复:
看看增加以下[InverseProperty("")]  属性能否解决这个问题
http://blog.csdn.net/hanjun0612/article/details/52838692


多谢!