C# 使用EF更新主详细信息的正确方法是什么

C# 使用EF更新主详细信息的正确方法是什么,c#,entity-framework,dbcontext,master-detail,C#,Entity Framework,Dbcontext,Master Detail,我正在处理脱机主控详细信息,如下所示: 目前我正在删除集合,然后再次添加它们。即使不是集合的所有项都已修改 这是进行更新的正确方法吗 编辑: 根据注释添加了代码和一些修改: CreateMasterFromView(){ Master aMaster = new Master(); aMaster.MasterId = View.Id // I set Id because I'm editing this master aMaster.Mast

我正在处理脱机主控详细信息,如下所示:

目前我正在删除集合,然后再次添加它们。即使不是集合的所有项都已修改

这是进行更新的正确方法吗

编辑:

根据注释添加了代码和一些修改:

  CreateMasterFromView(){
       Master aMaster = new Master();
       aMaster.MasterId = View.Id  // I set Id because I'm editing this master
       aMaster.MasterValue = "Some value";

       foreach (var detail in View.Details)
       {
         Detail aDetail = new Detail();
         aDetail.DetailValue = View.DetailValue;
         aDetail.MasterId = View.Id // 
         aMaster.Details.add(aDetail);
       }    
        Save(aMaster);
    }

Save (Master aMaster){
    if (aMaster.MasterId != 0)
    {                  
        var oldDetails = Dba.Details.Where(detail=> detail.MasterId == aMaster.Id);
        foreach (var oldDetail  in oldDetails )
                    {
                       Dba.Details.Remove(oldDetail);
                    }
        foreach (var detail in aMaster.Details)
                    {
                        Dba.Entry(detail).State = EntityState.Added;
                    }
    }
    Dba.Entry(aMaster).State = EntityState.Modified;
    Dba.SaveChanges();
}

我不是100%确定,但这应该有效:

Master.Details.Clear();
Dba.SaveChanges();

EF对其实体进行大量跟踪,不要像处理SQL那样尝试使用EF。

我不是100%确定,但这应该可以:

Master.Details.Clear();
Dba.SaveChanges();

EF对其实体进行大量跟踪,不要像使用SQL那样尝试使用EF。

当您的实体处于非连接状态时(在多层应用程序的域外,这是常见情况),以下示例非常有用:

公共类主控
{
公共长主ID{get;set;}
公共对象主值{get;set;}
公共虚拟ICollection详细信息{get;set;}
}
公共类详细信息
{
公共长细节ID{get;set;}
公共长主ID{get;set;}
公共对象详细信息值{get;set;}
公共主控主机{get;set;}
}
公共类YourContext:DbContext
{
公共数据库集主机{get;set;}
公共数据库集详细信息{get;set;}
}
公开课考试
{
public void ChangeMasterValue(主控、对象newValue)
{
使用(var context=newyourcontext())
{
context.Master.Attach(Master);
master.MasterValue=newValue;
SaveChanges();
}
}
public void DeleteAllDetailsFromMaster(主控)
{
使用(var context=newyourcontext())
{
context.Master.Attach(Master);
master.Details.Clear();
SaveChanges();
}
}
public void AddDetailToMaster(Master-Master,Detail-newDetail)
{
使用(var context=newyourcontext())
{
context.Master.Attach(Master);
master.Details.Add(newDetail);
SaveChanges();
}
}
public void DeleteDetailFromMaster(Master-Master,Detail-detailToDelete)
{
使用(var context=newyourcontext())
{
context.Master.Attach(Master);
master.Details.Remove(detailToDelete);
SaveChanges();
}
}
public void UpdateMaster(主控)
{
使用(var context=newyourcontext())
{
context.Master.Attach(Master);
context.Entry(master.State=EntityState.Modified;
SaveChanges();
}
}
}

当您的实体处于非连接状态时(在多层应用程序的域之外,这是常见的情况),以下示例非常有用:

公共类主控
{
公共长主ID{get;set;}
公共对象主值{get;set;}
公共虚拟ICollection详细信息{get;set;}
}
公共类详细信息
{
公共长细节ID{get;set;}
公共长主ID{get;set;}
公共对象详细信息值{get;set;}
公共主控主机{get;set;}
}
公共类YourContext:DbContext
{
公共数据库集主机{get;set;}
公共数据库集详细信息{get;set;}
}
公开课考试
{
public void ChangeMasterValue(主控、对象newValue)
{
使用(var context=newyourcontext())
{
context.Master.Attach(Master);
master.MasterValue=newValue;
SaveChanges();
}
}
public void DeleteAllDetailsFromMaster(主控)
{
使用(var context=newyourcontext())
{
context.Master.Attach(Master);
master.Details.Clear();
SaveChanges();
}
}
public void AddDetailToMaster(Master-Master,Detail-newDetail)
{
使用(var context=newyourcontext())
{
context.Master.Attach(Master);
master.Details.Add(newDetail);
SaveChanges();
}
}
public void DeleteDetailFromMaster(Master-Master,Detail-detailToDelete)
{
使用(var context=newyourcontext())
{
context.Master.Attach(Master);
master.Details.Remove(detailToDelete);
SaveChanges();
}
}
public void UpdateMaster(主控)
{
使用(var context=newyourcontext())
{
context.Master.Attach(Master);
context.Entry(master.State=EntityState.Modified;
SaveChanges();
}
}
}

更新实体有两种方法:

  • 从数据库中获取旧实体,然后更新已更改的属性并 调用保存更改
  • 直接将新实体附加到db并调用save changes。(无需从db获取旧实体)
  • 在您的情况下,可能是这样的:

    if (Master.MasterId != 0)
    {
         var oldDetails = Dba.Detail.Where(det => det.MasterId == Master.MasterId);
         foreach (var olddetail in oldDetails)
         {
               // don't call remove here just update new values in those properties which are changed like this   
         }
         //no need to set modified state because this olddetail is in current request
    }
    Dba.SaveChanges();}
    
    或者第二种方式:

    if (Master.MasterId != 0)
    {
        Dba.Entry(Master).State = EntityState.Modified;
    }
    Dba.SaveChanges();
    

    有两种方法可以更新实体:

  • 从数据库中获取旧实体,然后更新已更改的属性并 调用保存更改
  • 直接将新实体附加到db并调用save changes。(无需从db获取旧实体)
  • 在您的情况下,可能是这样的:

    if (Master.MasterId != 0)
    {
         var oldDetails = Dba.Detail.Where(det => det.MasterId == Master.MasterId);
         foreach (var olddetail in oldDetails)
         {
               // don't call remove here just update new values in those properties which are changed like this   
         }
         //no need to set modified state because this olddetail is in current request
    }
    Dba.SaveChanges();}
    
    或者第二种方式:

    if (Master.MasterId != 0)
    {
        Dba.Entry(Master).State = EntityState.Modified;
    }
    Dba.SaveChanges();
    

    你应该达到什么目标?插入新母版?是否更新标量主属性?是否删除所有主关系?所有这些?@Szer我将编辑这个问题,我试图用新的细节和新的属性值更新我的主人。你想做什么?您提到更新详细信息,但代码会删除详细信息。如果要删除母版的详细信息,只需对其调用
    Remove
    ,不要重新加载。@PanagiotisKanavos很抱歉代码混淆了。我正在尝试使用(新的、修改的或删除的)详细信息更新主实体。您是否正在尝试保存对PK值的更改?您应该实现什么?插入新母版?是否更新标量主属性?是否删除所有主关系?所有这些?@Szer我会的