2012-04-03 79 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

相關問題