C# 如何在实体框架中更新相关实体
我有一个MVC项目,首先使用实体框架代码和数据库的POCO对象。例如: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;}
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;}
}