最近在項目過程當中遇到了保存數據的需求,對實體類的部分數據進行保存,打算採用反射+自定義特性來實現數據保存,利於擴展
1. 採用反射實現可以靈活獲取要保存的數據,因爲只須要保存實體類(Model)的部分數據,所以採用自定義特性標記須要保存的數據,同時數據要求以.csv格式保存,添加自定義特性有利於對錶頭進行描述
2. 實現自定義特性測試
public class ResultAttribute : Attribute { private bool _IsSave; /// <summary> /// 是否保存 /// </summary> public bool IsSave { get { return _IsSave; } set { _IsSave = value; } } private string _SaveName; /// <summary> /// .csv文件第一行的名稱 /// </summary> public string SaveName { get { return _SaveName; } set { _SaveName = value; } } }
public class TestResultModel:ViewModelBase { private int _TestNumber; /// <summary> /// 序號 /// </summary> [EquationResult(SaveName = "序號", IsSave = true)] public int TestNumber { get { return _TestNumber; } set { _TestNumber = value; RaisePropertyChanged(); } } private string _TestResult; /// <summary> /// 測試結果 /// </summary> [EquationResult(SaveName = "測試結果", IsSave = true)] public string TestResult { get { return _TestResult; } set { _TestResult = value; RaisePropertyChanged(); } } private DateTime _TestTime; /// <summary> /// 測試時間 /// </summary> [EquationResult(SaveName = "測試時間", IsSave = true)] public DateTime TestTime { get { return _TestTime; } set { _TestTime = value; RaisePropertyChanged(); } } private string _MeterSn; /// <summary> /// 儀器SN號 /// </summary> public string MeterSn { get { return _MeterSn; } set { _MeterSn = value; RaisePropertyChanged(); } } }
/// <summary> /// 得到要保存的數據 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="tClass"></param> /// <param name="IsHead">是否是第一行的表頭</param> /// <returns></returns> private string GetSaveStr<T>(T tClass, bool IsHead = false) where T : class { StringBuilder sb = new StringBuilder(); //msdn:GetProperties方法不按特定順序(如字母順序或聲明順序)返回屬性。 你的代碼不能依賴屬性的返回順序,由於該順序會有所不一樣。 PropertyInfo[] infoarr = tClass.GetType().GetProperties(); foreach (var property in infoarr) { if (property.GetCustomAttribute(typeof(EquationResultAttribute), false) is EquationResultAttribute bute) { if (bute.IsSave && IsHead) { sb.Append(bute.SaveName + ","); } else if (bute.IsSave && !IsHead) { sb.Append(property.GetValue(tClass).ToString() + ","); } else { ;//無代碼 } } } return sb.ToString(); } /// <summary> /// 保存測試信息 /// </summary> /// <param name="listModel"></param> public void SaveTestDataToCsv(List<TestDataModel> listModel) { using (FileStream fs = new FileStream(CsvSavePath, FileMode.OpenOrCreate, FileAccess.Write)) { using (StreamWriter sw = new StreamWriter(fs,Encoding.Default)) { sw.BaseStream.Seek(0, SeekOrigin.Begin); //設置流的起始位置爲開始 string data = GetSaveStr(listModel[0], true); //寫入第一行 sw.WriteLine(data); //寫入數據流 sw.Flush(); for (int i = 0; i < listModel.Count; i++) { sw.BaseStream.Seek(0, SeekOrigin.End); data = GetSaveStr(listModel[i]); sw.WriteLine(data); //寫入數據流 sw.Flush(); } } } }