Similar questions have been asked but cannot find a solution that works well.
What I have is a rather large object (Viper object) that has several sub objects and Lists. I will receive a new instance of a Viper object several times a second and I need to merge that data into a “master” Viper object. If the property is null skip it if not replace it. Some properties that are lists will just be replaced by the new property, some list properties will just append the new list to the existing one.
Point being, there are properties that need some custom logic to determine how to perform the merge. The question is should I use something like AutoMapper/Value Injector or just write a custom Merge command in the data model that takes another Viper object? This needs to be as efficient as possible since it will be called a lot.
Here is the data model:
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; }
}
I would use Auto Mapper or Value Injector as you mentioned. Especially if your property names are similiar across objects, you barely need to write any code. For the custom mappings, it is very easy to write custom functions to pass to the mapping method. Very useful. Quick psuedo code of what that would look like: