我如何检查属性是不是在更新前实际更改

Posted

技术标签:

【中文标题】我如何检查属性是不是在更新前实际更改【英文标题】:how do i check if property actually change before an update我如何检查属性是否在更新前实际更改 【发布时间】:2017-02-27 10:13:11 【问题描述】:

我使用的是 EF 5(不是 6)。我有一个以下类的对象,它使用 EF 在 DB 中。

public class Student

  public string Name  get; set; 
  public int Age  get; set; 
  public DateTime DOB  get; set;

稍后,

我收到了对同一对象/记录进行更新的请求。

但在进行更新调用之前,我想交叉比较属性是否实际更改,因为我可能会获得相同的更新记录,所以不想进行盲目更新。

 var student = _context.Students.select(x =>x.Name == "").first();
 student.name = "";
 student.age = "";
 student.DOB = "";
_context.Entry(student).State = EntityState.Modified;
_context.saveChanges();

EF 是否为我提供了一些内置方法?

或者,我需要逐一交叉比较每个属性并做出决定?我可以拥有 20 个属性...

有什么想法吗?

【问题讨论】:

"I may get the same record for an update" 究竟是什么意思?你的记录没有主键吗? 拥有主键会对我的问题产生什么影响?我保存的记录有主键。后来有人通过发送 Name、Age 和 DOB 参数调用了相同的方法。现在我需要决定是只进行盲目更新调用还是至少先比较属性?除非我遗漏了一些关于 EF 的内容 如果你删除_context.Entry(student).State = EntityState.Modified;这行,EF会帮你检查。 EntityState.Modified 在您的情况下是无用的,因为您正在更新的实体已被上下文跟踪 - 因此您可以删除它而不会造成任何伤害。 EntityStates 通常用于分离上下文 如果您想知道哪些字段已更改以及更改为什么值 - 那么您应该为此编写自己的方法,EF 不会为您做。 【参考方案1】:

从 EF 6 开始

context.ChangeTracker.HasChanges()

请参考文档

检查 DbContext 是否正在跟踪任何新的、已删除的或更改的实体或关系,如果调用 SaveChanges,这些实体或关系将发送到数据库。

DBChangeTracker Class

或者你可以从这个博客阅读这个方法Secrets of DetectChanges

更新: 对于 EF 5,有一个替代方案

return this.ChangeTracker.Entries().Any(e => e.State == EntityState.Added
                                              || e.State == EntityState.Modified
                                              || e.State == EntityState.Deleted);

这个答案不是我的,我是从answer 那里得到的,所以请给正确的人。

【讨论】:

不幸的是我不是 EF 6,甚至不会很快去 EF 6。 @simbada 抱歉没有指定版本,仅供参考 @simbada 如果您的问题特定于某个版本,请将该重要信息添加到您的问题中。【参考方案2】:

以下声明:

_context.Entry(student).State = EntityState.Modified;
_context.saveChanges();

将更新实体的所有相关字段,从而标记为脏。

后面的代码是这样的:

UPDATE student
SET Value 1 = 'whatever student name is',
    Value 2 = 'whatever student name is'
WHERE Id = 123; 

如果要更新具体值,请使用

_context.Student.Attach(student)

后面的代码如下所示:

    UPDATE student
    SET Value 1 = 'whatever student name is'
WHERE Id = 123;

如果你想检查更新之前属性是否改变覆盖你的对象的equals方法并比较你想要的属性:

public override bool Equals(object obj)

    return MyProperty == ((MyObject)obj).MyProperty

【讨论】:

【参考方案3】:

Equals 方法和IEquatable<T> 接口可用于了解两个对象是否相等,但它们不会让您知道对象之间的差异。

【讨论】:

以上是关于我如何检查属性是不是在更新前实际更改的主要内容,如果未能解决你的问题,请参考以下文章

如何检查记录是不是更新?

如何检查程序集是不是已更改

Laravel:与观察者检查列是不是在更新时更改

如何让客户实际时间和时区执行系统时间检查

当应用程序在后台时,如何检查我的 UIDocument 是不是已通过 iCloud 更新?

如何在解析之前检查 XML 中是不是存在属性和标签?