在EF核心中执行部分更新且从不更新某些属性的最佳方法是什么? [英] What is the best way to perform partial updates in EF core and never update certain properties?
问题描述
我知道您可以执行var myObj = _db.MyTable.FirstOrDefault(x => x.Id == id)
之类的操作,然后更新 myObj
属性要更新的属性,但是有更好的方法来更新说出 myObj
的10个属性中的6个并保留
I know you can do something like var myObj = _db.MyTable.FirstOrDefault(x=>x.Id==id)
and then update myObj
property by property that you want to update but is there a better way to update say 6 out of 10 properties of myObj
and leave the other 4 alone or have them marked as a way that they are only set once and never updateable from ef core?
public class MyObject
{
public string Id { get; set; }
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public string Prop3 { get; set; }
public string Prop4 { get; set; }
public string Prop5 { get; set; }
public string Prop6 { get; set; }
public string Prop7 { get; set; }
public string Prop8 { get; set; }
public string Prop9 { get; set; }
}
public void UpdateObj(MyObject ojToUpdate)
{
//Is there a better way to write this function if you only want to update a set amount of properties
var myObj = _db.MyObject.First(x=>x.Id==ojToUpdate.Id);
myObj.Prop1 = objToUpdate.Prop1;
myObj.Prop2 = objToUpdate.Prop2;
myObj.Prop3 = objToUpdate.Prop3;
myObj.Prop4 = objToUpdate.Prop4;
myObj.Prop5 = objToUpdate.Prop5;
myObj.Prop6 = objToUpdate.Prop6;
_db.SaveChanges();
}
很明显,您可以编写 _db.MyObject之类的东西。更新(objToUpdate)
。该声明的问题在于,用户可以更新道具4/5/6,但我不希望他们进行更新。
是的,我知道您可以编写 _db.Entry(myObj).CurrentValues.SetValues(objToUpdate)
,然后调用保存更改,但这将超过我想要的行驶属性
Obviously you can write something like _db.MyObject.Update(objToUpdate)
. The problem with this statement is the user can update prop 4/5/6 which I don't want them to update.
Yes I know you can write _db.Entry(myObj).CurrentValues.SetValues(objToUpdate)
and then call save changes but that will over ride properties that i want to be generated once and never modified again.
提前感谢。
推荐答案
从EF Core 2.0开始,可以使用 IProperty.AfterSaveBehavior
属性:
Starting with EF Core 2.0, you can use IProperty.AfterSaveBehavior
property:
获取一个值,该值指示在将实体保存到数据库之后是否可以修改此属性。
Gets a value indicating whether or not this property can be modified after the entity is saved to the database.
如果抛出,然后在数据库中存在该实体后,如果为此属性分配新值,将引发异常。
If Throw, then an exception will be thrown if a new value is assigned to this property after the entity exists in the database.
如果忽略,那么将忽略对数据库中已经存在的实体的属性值的任何修改。
If Ignore, then any modification to the property value of an entity that already exists in the database will be ignored.
您需要的是忽略
选项。在撰写本文时,还没有专用的流利API方法,但是在更新过程中设置显式值包含一个示例,您可以做到这一点。
What you need is the Ignore
option. At the time of writing there is no dedicated fluent API method for that, but Setting an explicit value during update contains an example how you can do that.
以您的示例为例:
modelBuilder.Entity<MyObject>(builder =>
{
builder.Property(e => e.Prop7).Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
builder.Property(e => e.Prop8).Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
builder.Property(e => e.Prop9).Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
});
现在都
public void UpdateObj(MyObject objToUpdate)
{
var myObj = _db.MyObject.First(x => x.Id == objToUpdate.Id);
_db.Entry(myObj).CurrentValues.SetValues(myObjToUpdate);
_db.SaveChanges();
}
和
public void UpdateObj(MyObject objToUpdate)
{
_db.Update(myObjToUpdate);
_db.SaveChanges();
}
将忽略 Prop7
, Prop8
和 Prop9
值传递的 myObjToUpdate
。
will ignore Prop7
, Prop8
and Prop9
values of the passed myObjToUpdate
.
更新(EF Core 3.0 +)上述属性已由 GetAfterSaveBehavior 和 SetAfterSaveBehavior 扩展方法。
Update (EF Core 3.0+) The aforementioned property has been replaced with GetAfterSaveBehavior and SetAfterSaveBehavior extension methods.
这篇关于在EF核心中执行部分更新且从不更新某些属性的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!