Asp.net mvc 是否可以仅自动更新现有实体对象上的选定属性而不接触其他属性
假设我在实体类Asp.net mvc 是否可以仅自动更新现有实体对象上的选定属性而不接触其他属性,asp.net-mvc,asp.net-mvc-3,entity-framework,entity-framework-4,objectcontext,Asp.net Mvc,Asp.net Mvc 3,Entity Framework,Entity Framework 4,Objectcontext,假设我在实体类public bool isActive等中有一组布尔属性。这些值将通过在web应用程序中设置复选框来操作。我一次只回发一个已更改的名称/值对和主键,比如{isActive:true,NewsPageID:34},默认的模型绑定器将创建一个仅设置了这两个属性的NewsPage对象。现在,如果我运行下面的代码,它不仅会更新在模型绑定器创建的NewsPage对象上设置的属性值,而且当然还会尝试为现有实体对象的所有其他未设置的值设置为null,因为它们没有在模型绑定器创建的NewsPag
public bool isActive
等中有一组布尔属性。这些值将通过在web应用程序中设置复选框来操作。我一次只回发一个已更改的名称/值对和主键,比如{isActive:true,NewsPageID:34}
,默认的模型绑定器将创建一个仅设置了这两个属性的NewsPage对象。现在,如果我运行下面的代码,它不仅会更新在模型绑定器创建的NewsPage对象上设置的属性值,而且当然还会尝试为现有实体对象的所有其他未设置的值设置为null,因为它们没有在模型绑定器创建的NewsPage对象上设置
是否可能以某种方式告诉EntityFramework不要查看设置为null的属性,并尝试将这些更改保留回检索到的实体对象和数据库?也许我可以编写一些代码,只使用model binder创建的NewsPage对象上的非null值及其属性名,并且只尝试更新这些特定属性
[HttpPost]
public PartialViewResult SaveNews(NewsPage Np)
{
Np.ModifyDate = DateTime.Now;
_db.NewsPages.Attach(Np);
_db.ObjectStateManager.ChangeObjectState(Np, System.Data.EntityState.Modified);
_db.SaveChanges();
_db.Dispose();
return PartialView("MonthNewsData");
}
我当然可以做下面的事情,但我觉得这不是最佳解决方案。特别是考虑到我需要设置6个布尔属性
[HttpPost]
public PartialViewResult SaveNews(int NewsPageID, bool isActive, bool isOnFrontPage)
{
if (isActive != null) { //Get entity and update this property }
if (isOnFontPage != null) { //Get entity and update this property }
}
你可以有两种选择
新闻页
模型作为操作参数。可以创建包含必要特性的自定义视图模型。在操作中,您必须调用db以获取完整的新闻页面
实例,并仅更新视图模型中的相应属性API不是强类型的,但您可以按如下方式执行
DbContext
API对此有更好的支持
[HttpPost]
public PartialViewResult SaveNews(NewsPage Np)
{
Np.ModifyDate = DateTime.Now;
_db.NewsPages.Attach(Np);
var entry = _db.ObjectStateManager.GetObjectStateEntry(Np);
var cv = entry.CurrentValues;
if (isActive)
{
cv.SetBoolean(cv.GetOrdinal("isActive"), true);
}
_db.SaveChanges();
_db.Dispose();
return PartialView("MonthNewsData");
}
有点难看,但在我的例子中,这样做不需要创建和注册自定义模型绑定器,也不需要使用多个if语句
[HttpPost]
public void SaveNews(string propname, bool propvalue, int PageID)
{
var prop = typeof(NewsPage).GetProperties().FirstOrDefault(x => x.Name.ToLower() == propname.ToLower());
var Np = _db.NewsPages.FirstOrDefault(x => x.PageID == PageID);
prop.SetValue(Np, propvalue, null);
Np.ModifyDate = DateTime.Now;
_db.SaveChanges();
_db.Dispose();
}
将未更改的道具传递给模型绑定器可能会更容易,或者编写一个自定义道具并在那里获取完整的对象。模型绑定器解决方案听起来是可行的,考虑到它将只匹配集合,并且只针对模型发布名称/值对,在我的情况下,模型可能是数据库中的完整对象。然而,ViewModel方法在处理NewsPage对象时并没有任何优势。当然,我可以为name、value和pageid设置单独的属性,但这也可以从NewsPage对象中提取。