【问题标题】:How to update child list in entity framework?如何更新实体框架中的子列表?
【发布时间】:2019-12-26 12:31:50
【问题描述】:

这些是模型:

public class Contact
{
    public Contact() 
    {
        Emails = new List<Email>(); 
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Address { get; set; }
    public ICollection<Email> Emails { get; set; }

}
 public  class Email
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual int ContactId { get; set; }
}

在我的详细信息页面上,用户可以添加更多电子邮件、删除现有的...等...或更改现有的电子邮件。 如何更新收藏? 我试试这个:

    var contactFromDb = db.Contacts.Include("Emails").Include("Telephones").Where(x => x.Id == contact.Id).FirstOrDefault();

      contactFromDb.Address = contact.Address;
      contactFromDb.Name = contact.Name;
      contactFromDb.Surname = contact.Surname;
      contactFromDb.Telephones = contact.Telephones;
      contactFromDb.Emails = contact.Emails;

字符串属性更新得很好,我尝试以同样的方式更新集合,但我得到了重复的值。如何更新邮件?

【问题讨论】:

  • 你需要比较集合,哪些是新实体,然后添加它们,哪些删除实体然后删除它们,哪些现有实体然后更新它们
  • 在您的电子邮件类中,contactid 属性不应是虚拟的。它应该由外键属性标记并添加带有类联系人的虚拟属性。

标签: c# asp.net-mvc entity-framework


【解决方案1】:

首先删除已删除的电子邮件:

var contactFromDb = db.Contacts.Include("Emails").Include("Telephones").FirstOrDefault(x => x.Id == updatedContact.Id);
contactFromDb.Address = updatedContact.Address;
contactFromDb.Name = updatedContact.Name;
contactFromDb.Surname = updatedContact.Surname;

// Delete removed emails
var emailsToDelete = (from email in contactFromDb.Emails
                        let item = updatedContact.Emails.SingleOrDefault(i => i.Id == email.Id)
                        where item == null
                        select email).ToList();
if (emailsToDelete.Any())
{
    foreach (var email in emailsToDelete)
    {
        db.Entry(email).State = EntityState.Deleted;
    }
}

更新后编辑的电子邮件:

foreach (var email in updatedContact.Emails)
{
    // If id of an email is not equal to 0, it's not new email and it should be updated
    if (email.Id > 0)
    {
        var emailInDb = contactFromDb.Emails.Single(e => e.Id == email.Id);
        db.Entry(emailInDb).CurrentValues.SetValues(email);
        db.Entry(emailInDb).State = EntityState.Modified;
    }
}

最后通过调用db.SaveChanges() 新电子邮件ID 为0 将被插入,您可以为Phones 重复此循环。

【讨论】:

  • 如果电子邮件为零,我应该将电子邮件添加到数据库。它似乎工作,但有更优雅的解决方案。对于电话和其他收藏品,我必须重复这一点。一点都不优雅。
  • 在断开连接的环境中我认为没有更优雅的解决方案。
【解决方案2】:

对于子实体 - 最简单的方法是将它们全部删除并添加新的。

var contactFromDb = db.Contacts.Include("Emails").Include("Telephones").Where(x => x.Id == contact.Id).FirstOrDefault();

contactFromDb.Address = contact.Address;
contactFromDb.Name = contact.Name;
contactFromDb.Surname = contact.Surname;
contactFromDb.Telephones = contact.Telephones;
db.Entry(contactFromDb).State = System.Data.EntityState.Modified;
foreach(Email email in contactFromDb.Emails)
{
    db.Entry(email).State = System.Data.EntityState.Deleted;
}
contactFromDb.Emails.AddRange(contact.Emails);
db.SaveChanges();

【讨论】:

    【解决方案3】:

    用这个通用的sub来标记子状态,好用

    注意事项:

    • PromatCon:实体对象
    • amList:是您要添加或修改的子列表
    • rList:是您要删除的子列表
    updatechild(objCas.ECC_Decision, PromatCon.ECC_Decision.Where(c => c.rid == objCas.rid & !objCas.ECC_Decision.Select(x => x.dcid).Contains(c.dcid)).toList())
    
    public void updatechild<Ety>(ICollection<Ety> amList, ICollection<Ety> rList)
    {
        if (amList != null)
        {
            foreach (var obj in amList)
            {
                var x = PromatCon.Entry(obj).GetDatabaseValues();
                if (x == null)
                    PromatCon.Entry(obj).State = EntityState.Added;
                else
                    PromatCon.Entry(obj).State = EntityState.Modified;
            }
        }
    
        if (rList != null)
        {
            foreach (var obj in rList.ToList())
                PromatCon.Entry(obj).State = EntityState.Deleted;
        }
    }
    
    PromatCon.SaveChanges()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-07
      • 2017-10-22
      相关资源
      最近更新 更多