【问题标题】:C# On property change, run logicC#关于属性更改,运行逻辑
【发布时间】:2018-04-12 07:31:52
【问题描述】:

我有一个 C# 实体,它首先通过数据库自动生成:

public partial class Zone
{
    public Guid LocationId {get; set;}
    ...
}

我需要做的是运行一个函数,Process() 每当 LocationId 改变时。现在通常我会更改 setter 并完成工作,但是因为这是首先通过数据库自动生成的,所以 “如果重新生成代码,对文件的任何手动更改都将被覆盖。”

这里最好的方法是什么?

目前的想法是创建一个新的局部类来做这样的事情:

public partial class Zone
{
    private Guid _pendingLocationId
    public Guid PendingLocationId {
      get { return _pendingLocationId }
      set { 
        Guid updatedLocation = Process(value) ?? value;
        _pendingLocationId = updatedLocation;
        locationId = updatedLocation;
      }
    }
}

请注意;不幸的现实是,我们在这个阶段将新框架或库集成到应用程序中的可能性可能为零。


响应可能的duplicate标志;除非我读错了,否则这将需要我们将所有 Zone 引用重新映射/封装到一个新类中,不仅将其推送到所有视图,而且还要编辑许多 linq 查询等。如果有人能找出原因将是我自己建议的解决方案的首选解决方案,请告诉我。

【问题讨论】:

标签: c# entity-framework


【解决方案1】:

最少侵入性的方法可能是使用 AOP 模式,例如,使用 PostSharp 框架:少于 2 行代码

[NotifyPropertyChanged]  //<---Add this attributes to the class
public class Zone 
{ 
    public Guid LocationId {get; set;}
    ...

}

挂钩更改的事件并添加您自己的处理程序

//Zone instance;
((INotifyPropertyChanged) instance).PropertyChanged += ZoneOnPropertyChanged;

更多详情请关注here


更新:OP提到将其他库集成到应用程序中的可能性为零,我只是好奇,你不使用nuget吗?这个零机会的原因是什么?在我个人看来,如果已经有一个库可以提供所需的功能,你应该而不是不重新发明轮子。

如果许可成本是问题,或者它是矫枉过正或沉重为了这个问题而引入这个庞大的库,我认为Fody,一个可以考虑 PostSharp 的免费开源替代品。更具体地说是PropertyChanged.Fody 包,它非常独立、紧凑且重量轻

【讨论】:

  • 这可能会解决我们的问题,只需查看上面的示例。不幸的是,现实情况是我们在这个阶段将新框架或库集成到应用程序中的可能性可能为零。我现在也更新了问题以说明这一点。
【解决方案2】:

我建议使用AutoMapper

您可以编写另一个具有相同名称和属性的类(使用 INPC),但在不同的命名空间中。然后,每次获取数据库时,都使用 Automapper 将数据映射到通知类,每次将数据保存到数据库时,都会将其映射回来。

这样您只需要使用您的类更改代码中的命名空间,并将这样的代码添加到您的存储库中:

var dtos = args.Select(x =&gt; Mapper.Map&lt;Zone&gt;(x)).ToList();

【讨论】:

    【解决方案3】:

    将业务实体映射到您的数据库实体(通过 AutoMapper),然后在您的业务实体中,合并 INotifyPropertyChanged 接口。

    下面的伪代码。这将使您的数据库与业务实体分离并允许独立更改。

    namespace DBEntity {
        public class Customer {
             public int Id { get; set; }  ...
        }
    }
    
    namespace BizEntity {
        public class Customer : INotifyPropertyChanged {
             private int id;
             public int Id { 
                      get { return this.id } ; 
                      set { 
                           this.id = value; 
                           PropertyChanged(Id...);
                           }
                      }
             NotifyPropertyChanged() {
                        ....
             }
    
    var dbCustomer = GetCustomerFromDB()
    var cust = AutoMapper.Mapper.Map<DBEntity.Customer, BizEntity.Customer>(dbCustomer);
    
    // Update the property as per biz requirement
    cust.Id = 53656;      // Fires the Notification
    

    如果这有帮助,请告诉我。
    将 AutoMapper 视为一个新库,这将是最小的更改,并且此处不需要许可或学习曲线即可实现快速集成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-26
      • 2018-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多