在EF核心中执行部分更新并且永不更新某些属性的最佳方法是什么?

jac*_*ter 7 c# entity-framework entity-framework-core

我知道你可以做一些类似var的事情myObj = _db.MyTable.FirstOrDefault(x=>x.Id==id),然后myObj通过你想要更新的属性来更新属性,但是有更好的方法来更新10个属性中的6个myObj并留下其他4个或者将它们标记为它们的方式只设置一次,永远不能从ef核心更新?

    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();
    }
Run Code Online (Sandbox Code Playgroud)

显然你可以写类似的东西_db.MyObject.Update(objToUpdate).这个陈述的问题是用户可以更新道具4/5/6,我不希望他们更新.是的我知道你可以写_db.Entry(myObj).CurrentValues.SetValues(objToUpdate),然后调用保存更改,但这将超过我希望生成一次但永远不会再次修改的属性.

提前谢谢.

Iva*_*oev 11

从EF Core 2.0开始,您可以使用IProperty.AfterSaveBehavior属性:

获取一个值,该值指示在将实体保存到数据库后是否可以修改此属性.

如果抛出,则在实体存在于数据库中之后为此属性分配新值时,将抛出异常.

如果忽略,则将忽略对数据库中已存在的实体的属性值的任何修改.

你需要的是Ignore选项.在撰写本文时,没有专门的流畅API方法,但在更新期间设置显式值包含一个示例,说明如何执行此操作.

举个例子,像这样:

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;
});
Run Code Online (Sandbox Code Playgroud)

现在两个

public void UpdateObj(MyObject objToUpdate)
{
    var myObj = _db.MyObject.First(x => x.Id == objToUpdate.Id);
    _db.Entry(myObj).CurrentValues.SetValues(myObjToUpdate);
    _db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

public void UpdateObj(MyObject objToUpdate)
{
    _db.Update(myObjToUpdate);
    _db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

将忽略Prop7,Prop8Prop9传递的值myObjToUpdate.


kor*_*inp 6

如果您有实体:

public class Person
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public string Address { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

你运行:

var p = ctx.Person.First();
p.Name = "name updated";
ctx.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

EF将生成以下 SQL 语句:

在此处输入图片说明

您可以使用SQL Server Profiler验证它,如果您更新 6/10 属性也是如此。