Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在实体框架中更新相关实体_C#_Asp.net Mvc 3_Entity Framework_Ef Code First - Fatal编程技术网

C# 如何在实体框架中更新相关实体

C# 如何在实体框架中更新相关实体,c#,asp.net-mvc-3,entity-framework,ef-code-first,C#,Asp.net Mvc 3,Entity Framework,Ef Code First,我有一个MVC项目,首先使用实体框架代码和数据库的POCO对象。例如: public class ClassA { public int? Id {get; set;} public string Name { get; set;} public virtual ClassB B {get; set;} } public class ClassB { public int? Id {get;set;} public string Description {get;set;}

我有一个MVC项目,首先使用实体框架代码和数据库的POCO对象。例如:

public class ClassA
{
  public int? Id {get; set;}
  public string Name { get; set;}
  public virtual ClassB B {get; set;}
}

public class ClassB
{
  public int? Id {get;set;}
  public string Description {get;set;}
}
我有一个创建或编辑模型的ActionResult。问题是,当我调用此ActionResult来更新模型时,
model.B
已更改,关系未保存在数据库中。当调用ActionResult创建新对象时,它会按预期工作。我如何解决这个问题

public ActionResult Save(ClassA model)
{
  model.B = GetBFromDb(model.B.Id.Value);

  if(ModelState.IsValid)
  {
    if (id.HasValue)
    {
      context.Entry(model).State = System.Data.EntityState.Modified;
    }
    else
    {
      context.ClassAs.Add(model);
    }
    context.SaveChanges();
    // redirect to index etc.
  }
  return View("EditForm", model);
}
你不能简单地说:

context.Entry(model).State = System.Data.EntityState.Modified;
必须首先从上下文中检索实体,以便EF可以开始跟踪它。然后,在调用
context.SaveChanges()
之前,您需要对该实体应用任何更改


通过这种方式,EF正在跟踪
实体
,并知道如何对其应用更新。

如果附加并将状态设置为修改后的实体,框架将发送所有属性进行更新。您不必采取下面的水獭方法,因为这会导致整个单独的负载发生。如果这样做,那么只传递一个id,然后调用TryUpdateModel来填充表单中的属性,这是没有意义的

就个人而言,这里修改的attach有点干净,因为加载数据不需要完整的往返


我通过使用外键将
ClassA
更改为
ClassB
,并设置
BId
的值来解决这个问题:

public class ClassA
{
  public int? Id {get; set;}
  public string Name { get; set;}
  public int BId {get;set;} // foreign key to B
  public virtual ClassB B {get; set;}
}

为什么这个外键属性会代替EF生成的外键属性执行此任务?

谢谢!如何设置
entity.ClassB=null?似乎只是将其设置为null不起作用。恶心。。。context.Entry(model).State将使上下文查看是否正在跟踪模型,如果没有,它将开始跟踪模型。您不必执行另一个db查询来跟踪模型实例。Henkie在ocde中遇到的问题是,该方法只会更改传入的实体的状态。“已修改”状态设置不会应用于图表的其余部分。@JulieLerman谢谢,我找到了一些教程,这些教程也将状态设置为“已修改”。但是我仍然有一个问题,我的关系不会更新。我误读了@JulierMan的评论,认为她不关心上下文。条目(模型)。状态方法,因为一开始的单词“恶心”,我意识到恶心是回答者的名字!重读一遍,我相信使用context.Entry(model.State)是理想的方法。也许在恶心之前加上@是个好主意。哈哈!我只是用同样的方式读,因为两年后,它对我来说已经断章取义了。哈哈!好的catchin断开连接,当您没有外键时,会出现一些EF无法解决的漏洞&您必须验证额外的代码。否则它就看不到这种关系。有了FK属性,它是一个标量值,EF更容易跨进程跟踪。事实上,我在2012年1月写了一篇关于这个主题的数据点专栏!当您具有FK标量属性时,EF更易于使用。否则,许多您期望“正常工作”的功能将无法实现&itf迫使您更好地了解正在发生的事情以及如何提供所需的信息。对不起,我以前没有看到丢失的FK
public class ClassA
{
  public int? Id {get; set;}
  public string Name { get; set;}
  public int BId {get;set;} // foreign key to B
  public virtual ClassB B {get; set;}
}