2012-04-03 54 views
-1

已经提出了类似的问题,但是找不到可行的解决方案。 我所拥有的是一个相当大的对象(Viper对象),它有几个子对象和列表。我将每秒收到一个Viper对象的新实例,我需要将这些数据合并到一个“主”Viper对象中。如果该属性为空,则跳过它,如果不替换它。一些属性是列表只会被新属性取代,一些列表属性会将新列表追加到现有列表中。使用.Net中的另一个相同类型的对象更新对象的最佳方法是什么?

要点是,有些属性需要一些自定义逻辑来确定如何执行合并。问题是我应该使用像AutoMapper/Value Injector之类的东西,还是只在需要另一个Viper对象的数据模型中编写自定义Merge命令?这需要尽可能高效,因为它会被称为很多。

下面是数据模型:

public class Viper 
{ 
    #region INotifyPropertyChanged Members 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string property) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(property)); 
     } 
    } 
    #endregion 

    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public int ViperId { get; set; } 

    [DataMember] 
    public int CaseId { get; set; } 

    [DataMember] 
    public int RecordCount { get; set; } 

    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public string SerialNumber { get; set; } 

    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public string UserName { get; set; } 

    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public string GroupName { get; set; } 

    [DataMember] 
    public Byte Status { get; set; } 
    [DataMember] 
    public int CaseStage { get; set; } 

    [DataMember(IsRequired = false,EmitDefaultValue = false)] 
    public CaseDetail CaseDetail { get; set; } 

    private ViperMetaData _metaData; 
    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public ViperMetaData MetaData { 
     get { return _metaData; } 
     set 
     { 
      _metaData = value; 
      OnPropertyChanged("MetaData"); 
     } 
    } 

    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<CasePatientData> PatientDetailsTable1 { get; set; } 
    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<CasePatientData> PatientDetailsTable2 { get; set; } 
    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<CasePatientData> PatientDetailsTable3 { get; set; } 
    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<CasePatientData> PatientDetailsTable4 { get; set; } 

    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<CaseChannel> CaseChannelDataList { get; set; } // list of all channels available in a specific case/viper 

    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<EventsData> EventsDataList { get; set; } 


    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<ChannelData> ChannelDataList { get; set; } 

    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public CasePatientDetails CasePatientDetails { get; set; } 

    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<CaseFluids> CaseFluidsList { get; set; } 

    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<PatientTable> PatientTableNames { get; set; } 

    [DataMember] 
    public int? TimeOffset { get; set; } 

    [DataMember(IsRequired = false,EmitDefaultValue = false)] 
    public string Html { get; set; } 

    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<CaseDocument> CaseDocuments { get; set; } 
    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public Department Department { get; set; } 
    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<Gauge> Gauges { get; set; } 
    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<Region> Regions { get; set; } 
    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<BloodGasData> BloodGasDataList { get; set; } 
    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<CardioplegiaData> CardioplegiaDataList { get; set; } 
    [DataMember(IsRequired = false, EmitDefaultValue = false)] 
    public List<ComplianceDataUnit> ComplianceDataList { get; set; } 
} 

回答

0

正如你所说,我会用自动映射或价值注射器。特别是如果您的属性名称与对象相似,则几乎不需要编写任何代码。对于自定义映射,编写自定义函数以传递给映射方法非常简单。很有用。什么会像快速伪代码:

AutoMapper.Mapper.CreateMap<Viper, ViperDto>() 
    .ForMember(dest => dest.Property, opt => opt.NullSubstitute("N/A")); 
var merged = AutoMapper.Mapper.Map(viper, viperDTO); 
+0

我与AutoMapper(之前,所以非常环保从来没有使用过这一点)初始测试复制空了以及因此看起来我将不得不对每个属性自定义处理程序即使我不得不说,如果null为空,也不要复制。如果是这样的话,它似乎没有比编写自定义函数更少的代码。这听起来是对的还是我在AutoMapper中遗漏了一些东西?另外,我正在合并2个Viper对象,所以所有的属性都是相同的,除了一些在“传入”对象中为空。 – mdutra 2012-04-03 15:04:38

+0

Automapper包含一个NullSubstitution方法。它干净简洁。看到此页面的示例:http://taswar.zeytinsoft.com/2011/03/07/automapper-mapping-objects-part-1-of-7-nullsubsitution/ – 2012-04-03 15:06:30

+0

我必须用AutoMapper缺少一些东西。如果我必须为对象中的每个属性添加一个NullSubstitution条目,为什么比在数据模型本身中创建MergeWith函数更简单?另外,因为我正在使用数据绑定对象,所以我不能只替换它,我真的需要修改原始数据。与Viper对象和所有子对象中的自定义MergeWith函数相比,AutoMapper是否仍然可行且更容易? – mdutra 2012-04-03 20:19:01

相关问题