我知道您可以执行var myObj = _db.MyTable.FirstOrDefault(x=>x.Id==id)
之类的操作,然后根据要更新的属性更新myObj
属性,但有更好的方法可以更新{{1的10个属性中的6个属性并留下另外4个或者将它们标记为只设置一次并且永远不能从ef核心更新的方式?
myObj
显然你可以写一些像 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();
}
这样的东西。这个陈述的问题是用户可以更新道具4/5/6,我不希望他们更新。
是的我知道你可以写_db.MyObject.Update(objToUpdate)
然后调用保存更改,但这会超过我希望生成一次但永远不会再次修改的属性。
提前致谢。
答案 0 :(得分:9)
从EF Core 2.0开始,您可以使用IProperty.AfterSaveBehavior
属性:
获取一个值,该值指示在将实体保存到数据库后是否可以修改此属性。
如果Throw,则在实体存在于数据库中之后为此属性分配新值时,将抛出异常。
如果Ignore,则将忽略对数据库中已存在的实体的属性值的任何修改。
您需要的是Ignore
选项。在撰写本文时,没有专门的流畅API方法,但Setting an explicit value during update包含了如何做到这一点的示例。
举个例子,像这样:
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
的{{1}},Prop8
和Prop9
值。
答案 1 :(得分:2)
如果您有实体:
field WebDriver
你跑:
public class Person
{
public Guid Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
EF 将生成以下SQL语句:
您可以使用 SQL Server Profiler 进行验证,如果您更新6/10属性也是如此。
答案 2 :(得分:0)
您还可以在dbContext的OnModelCreating内部使用之前提到的AfterSaveBehavior,如下所示:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<someobject>(builder =>
{
builder.Property(i => i.CreatedAt).Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
});
现在,“ someobject”上的“ CreatedAt”属性将被第一次保存,然后在以后的更新中永远不会被修改。
答案 3 :(得分:0)
从3.1开始,可以通过使用SetAfterSaveBehavior()扩展方法来实现:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<someobject>(builder =>
{
builder.Property(i => i.CreatedAt).Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);
});