我需要为给定的实体对象更新除property1和property2之外的所有字段 有了这段代码:
[HttpPost]
public ActionResult Add(object obj)
{
if (ModelState.IsValid)
{
context.Entry(obj).State = System.Data.EntityState.Modified;
context.SaveChanges();
}
return View(obj);
}
如何更改它以向obj.property1和obj.property2添加例外,以便不使用此代码进行更新?
答案 0 :(得分:66)
假设您有一组要排除的属性:
var excluded = new[] { "property1", "property2" };
使用.NET 4.5上的EF5,您可以这样做:
var entry = context.Entry(obj);
entry.State = EntityState.Modified;
foreach (var name in excluded)
{
entry.Property(name).IsModified = false;
}
这在.NET 4.5上使用了EF5的一项新功能,即使以前将属性设置为修改后,也可以将属性设置为未修改。
在.NET 4上使用EF 4.3.1或EF5时,您可以这样做:
var entry = context.Entry(obj);
foreach (var name in entry.CurrentValues.PropertyNames.Except(excluded))
{
entry.Property(name).IsModified = true;
}
答案 1 :(得分:21)
您无法定义此类例外。但是,您可以将单个属性标记为已修改:
context.Entry(obj).Property(o => o.Property3).IsModified = true;
context.Entry(obj).Property(o => o.Property4).IsModified = true;
// etc.
请注意,将整个实体的状态标记为IsModified
后,不支持将false
设置为Modified
。
出于您的目的,我实际上更愿意从数据库加载实体,然后使用常规更改跟踪进行更新:
var objInDB = context.Objects.Single(o => o.Id == obj.Id);
obj.Property1 = objInDB.Property1;
obj.Property2 = objInDB.Property2;
context.Entry(objInDB).CurrentValues.SetValues(obj);
context.SaveChanges();
答案 2 :(得分:9)
这个问题已经很好地回答了,但我想为想要使用它的人提供一种扩展方法。
此代码是为EF 4.3.1
开发的//You will need to import/use these namespaces
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
//Update an entity object's specified columns, comma separated
//This method assumes you already have a context open/initialized
public static void Update<T>(this DbContext context, T entityObject, params string[] properties) where T : class
{
context.Set<T>().Attach(entityObject);
var entry = context.Entry(entityObject);
foreach(string name in properties)
entry.Property(name).IsModified = true;
context.SaveChanges();
}
用法示例
using (FooEntities context = new FooEntities())
{
FooEntity ef = new FooEntity();
//For argument's sake say this entity has 4 columns:
// FooID (PK), BarID (FK), Name, Age, CreatedBy, CreatedOn
//Mock changes
ef.FooID = 1;
ef.Name = "Billy";
ef.Age = 85;
context.Update<FooEntity>(ef, "Name", "Age"); //I only want to update Name and Age
}
答案 3 :(得分:1)
这是一个适用于.net CORE的更新,也许可以帮助需要通用语言并希望根据不同条件排除某些属性的人。
我正在使用反射来遍历属性并基于其属性值进行更新,在这种情况下,例如,我排除了null属性。
public virtual TEntity Update(TEntity entity)
{
dbSet.Attach(entity);
dbContext.Entry(entity).State = EntityState.Modified;
var entry = dbContext.Entry(entity);
Type type = typeof(TEntity);
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo property in properties)
{
if (property.GetValue(entity, null) == null)
{
entry.Property(property.Name).IsModified = false;
}
}
dbContext.SaveChanges();
return entity;
}
答案 4 :(得分:0)
上面的答案(大多数)使用DbContext。对于那些使用ObjectContext的人来说,这些解决方案是无法访问的。
以下是严格 ObjectContext 的解决方案( EF5 .NET 4.5 ):
ctx.AddObject("ENTITYNAME", item);
ctx.ObjectStateManager.ChangeObjectState(item, EntityState.Modified);
var entry = ctx.ObjectStateManager.GetObjectStateEntry(item);
entry.RejectPropertyChanges("PROPERTY_TO_EXCLUDE");