首页 > 解决方案 > 在从 Entity Framework 检索对象列表时可以忽略对象的 OnPropertyChanged 吗?

问题描述

我有一个对象,其中有一个 OnPropertyChanged 方法,如果其中一个属性(仅限于几个关键属性)发生更改,该方法会重新计算其他对象属性。这种重新计算有一点性能开销,这通常很好,因为它在应用程序中不经常调用。

但是,当我从 DBContext 中检索大量对象集合时,它需要很长时间,因为它为每个对象和该对象中的每个属性调用 OnPropertyChanged 方法。

如果它是由 EF 构建的,有没有办法告诉对象不要引发 OnPropertyChaged?我能想到的唯一方法是不在对象构造函数中设置处理程序,而是在加载后执行,但这不是很实用。


        protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "") => OnPropertyChanged(new PropertyChangedEventArgs(propertyName));

        public event PropertyChangedEventHandler PropertyChanged;
        public Container()
        {
            Notifications = new List<Notification>();
            IsClosed = false;
            PropertyChanged += Container_DemurrageArgsChanged;
            
            
        }

        void Container_DemurrageArgsChanged(object sender, PropertyChangedEventArgs e)
        {
            ///Recalculate the demurrge values if any of the below fields are updated.
            var DemurrageProperties = new List<string> { "DwellStart", "ContainerSize", "BonusDays", "GateOutTimeStamp", "FreeDays" ,"ChargeDemurrage","Holidays","DailyCharge"};
            if (DemurrageProperties.Contains(e.PropertyName)) UpdateDemurrageVals();

        }

标签: c#entity-framework

解决方案


另一种选择,您可以尝试使用 DBContext 事件ObjectContext.ObjectMaterialized Event

在作为查询或加载操作的一部分从数据源中的数据创建新实体对象时发生。

ObjectContext.ObjectMaterialized += OnEntityMaterialized;

但是您需要将实体标记为已加载或已物化

例如

private void OnEntityMaterialized(object sender, ObjectMaterializedEventArgs e)    
{
    var entity = e.Entity as BaseEntitie;
    if (entity != null)
        entity.IsMaterialized = true;
}

并更改 OnPropertyChanged

protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
    if (IsMaterialized)
    {
        OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }
}

新实体的注意点,因为不会引发事件。一种可能的解决方案是将条件更改为IsMaterialized || 编号 == 0


推荐阅读