我对EF的更新感到困惑。试图通过互联网找到相关的教程,但一无所获。
我有两个问题。
如何使用导航属性更新?(i。如果我更新某个实体,那么Ef(Linq to Entity)也会更新它的导航属性?)
[Table("master")]
public class masterViewModel
{
[Key,ForeignKey("address")]
public int id { get; set; }
public string name { get; set; }
public string lastName { get; set; }
public virtual address address { get; set; }
}
public class address
{
[Key]
public int id { get; set; }
public string city { get; set; }
public string state { get; set; }
}
即假设我有[masterViewModel.id=1 , masterViewModel.name="ABC" and masterViewModel.lastName=null ] [address.id=1 , address.city="xyz" and address.state=null]
然后在我看来我做了类似下面的事情
@Html.DisplayFor(modelModel => Model.name)
@Html.DisplayFor(modelModel => Model.address.city)
@Html.HiddenFor(x => x.id)@Html.HiddenFor(x => x.address.id)
@Html.EditorFor(modelModel => Model.address.state )
@Html.EditorFor(modelModel => Model.lastName)
因为我使用DisplayFor作为名称和字符串属性我在我的Controller操作时从不对这两个字段的值进行表单发布时,所以我需要一些只更新“state”(地址)和“lastName”(masterViewModel)属性的东西。
答案 0 :(得分:2)
一种方法是我们为@Kyle建议的其他属性的隐藏字段,但它导致从客户端到服务器并返回不需要的属性。它还会暴露额外的漏洞,因为恶意客户端可以创建发送请求,该请求将发送已修改的name
和city
,因此它将需要您服务器端的一些额外验证逻辑。
如果您不想更新所有属性,则必须将其告知EF。假设您收到带有相关地址的masterViewModel,并将修改过的数据添加到控制器的操作中。现在你可以这样做:
using (var context = new YourDbContext())
{
// This will inform EF about your existing masterViewModel and related address
context.MasterViewModels.Attach(masterViewModel);
// Now you must explicitly tell which properties you want to update
var masterEntry = context.Entry(masterViewModel);
masterEntry.Property(m => m.lastName).IsModified = true;
var addressEntry = context.Entry(masterViewModel.address);
addressEntry.Property(a => a.state).IsModified = true;
context.SaveChanges();
}
顺便说一下。在您的情况下,看起来地址可以是存储在主表中的复杂类型,而不是单独的实体。
答案 1 :(得分:0)
您是否只是在回发中获得name
和address.city
的值?
要解决此问题,请为这些属性添加隐藏字段。
@Html.HiddenFor(modelModel => Model.name)
@Html.HiddenFor(modelModel => Model.address.city)
现在,当表单回发到服务器时,将包含这些值。