实体框架:如果值没有变化,则取消属性更改

Ric*_*los 5 entity-framework

在实体对象上设置属性时,即使该值与之前完全相同,它也会将值保存到数据库中.反正有没有阻止这个?

例:

如果我加载一个Movie对象并且Title是"A",如果我再次将Title设置为"A"并且SaveChanges()我希望我不会在SqlProfiler中看到UPDATE语句但是我是.反正有没有阻止这个?

Cra*_*ntz 5

是的,你可以改变这个.但是,在当前版本的实体框架中,这样做并非易事.将来会变得更容易.

您看到此行为的原因是因为实体模型的默认代码生成.这是一个代表性的例子:

public global::System.Guid Id
{
    get
    {
        return this._Id;
    }
    set
    {
        // always!
        this.OnIdChanging(value);
        this.ReportPropertyChanging("Id");
        this._Id = global::System.Data.Objects.DataClasses
                               .StructuralObject.SetValidValue(value);
        this.ReportPropertyChanged("Id");
        this.OnIdChanged();
    }
}
private global::System.Guid _Id;
partial void OnIdChanging(global::System.Guid value);
partial void OnIdChanged();
Run Code Online (Sandbox Code Playgroud)

此默认代码生成是合理的,因为实体框架不知道您打算如何使用这些值的语义.属性中的类型可能具有可比性,也可能不具有可比性,即使它们存在,框架也无法知道您在所有情况下如何使用引用相等与值相等.对于像小数这样的某些值类型,它非常清楚,但从一般意义上说它并不明显.

另一方面,您知道您的代码,并可以自定义一些.麻烦的是这是生成的代码,因此您不能只是进入并编辑它.您需要接管代码生成,或者不必要.那么让我们来看看这三个选项.

接管代码生成

这里的基本方法是创建一个T4模板,该模板执行后面的代码,以及来自实体框架的默认代码生成.这是一个例子.这种方法的一个优点是实体框架将在下一版本中转向T4代,因此您的模板在未来版本中可能会运行良好.

消除代码生成

第二种方法是完全消除热电联产,并通过IPOCO手动更改跟踪支持.使用这种方法,您不需要更改代码的生成方式,也不会执行任何代码生成,而是通过实现多个接口为实体框架提供更改跟踪支持.有关详细信息,请参阅链接的帖子.

等待

另一个选择是暂时使用实体框架,并等到下一个版本获得您想要的行为.默认情况下,下一版本的Entity Framework将使用T4,因此自定义代码生成将非常容易.