Recently, I encountered the need to save data during the project process. I saved some data in the entity class and planned to use reflection + custom features to realize data storage, which is conducive to expansion.
1. Using reflection to achieve flexible access to the data to be saved. Since only part of the data of the entity class (Model) is needed, custom features are used to mark the data to be saved. At the same time, the data is required to be saved in .csv format. Adding custom features is conducive to describing the table header.
2. Implement custom features
public class ResultAttribute : Attribute { private bool _IsSave; /// <summary> /// Whether to save /// </summary> public bool IsSave { get { return _IsSave; } set { _IsSave = value; } } private string _SaveName; /// <summary> /// Name of the first line of the .csv file /// </summary> public string SaveName { get { return _SaveName; } set { _SaveName = value; } } }
Add custom tags in the class
After adding custom tags, you can identify the attributes and .csv header names to be saved during reflection.
public class TestResultModel:ViewModelBase { private int _TestNumber; /// <summary> /// Serial number /// </summary> [EquationResult(SaveName = "Serial Number", IsSave = true)] public int TestNumber { get { return _TestNumber; } set { _TestNumber = value; RaisePropertyChanged(); } } private string _TestResult; /// <summary> /// Test results /// </summary> [EquationResult(SaveName = "Test results", IsSave = true)] public string TestResult { get { return _TestResult; } set { _TestResult = value; RaisePropertyChanged(); } } private DateTime _TestTime; /// <summary> /// Test time /// </summary> [EquationResult(SaveName = "Test time", IsSave = true)] public DateTime TestTime { get { return _TestTime; } set { _TestTime = value; RaisePropertyChanged(); } } private string _MeterSn; /// <summary> /// Instrument SN number /// </summary> public string MeterSn { get { return _MeterSn; } set { _MeterSn = value; RaisePropertyChanged(); } } }
4. Use reflection to save data
/// <summary> /// Get the data to be saved /// </summary> /// <typeparam name="T"></typeparam> /// <param name="tClass"></param> /// <param name="IsHead">Is it the header of the first row?</param> /// <returns></returns> private string GetSaveStr<T>(T tClass, bool IsHead = false) where T : class { StringBuilder sb = new StringBuilder(); //msdn: The GetProperties method does not return properties in a specific order (such as alphabetical or declaration order). Your code cannot depend on the return order of properties, because that order will vary. PropertyInfo[] infoarr = ().GetProperties(); foreach (var property in infoarr) { if ((typeof(EquationResultAttribute), false) is EquationResultAttribute bute) { if ( && IsHead) { ( + ","); } else if ( && !IsHead) { ((tClass).ToString() + ","); } else { ;//No code } } } return (); } /// <summary> /// Save test information /// </summary> /// <param name="listModel"></param> public void SaveTestDataToCsv(List<TestDataModel> listModel) { using (FileStream fs = new FileStream(CsvSavePath, , )) { using (StreamWriter sw = new StreamWriter(fs,)) { (0, ); //Set the start position of the flow to start string data = GetSaveStr(listModel[0], true); //Write to the first line (data); //Write data stream (); for (int i = 0; i < ; i++) { (0, ); data = GetSaveStr(listModel[i]); (data); //Write data stream (); } } } }
5. When using reflection to obtain the attribute list, the order of the list may be inconsistent. You can add sorting characteristics to the custom attributes, set sorting values for each attribute, and then obtain sorting characteristics after the reflection to obtain the attribute list at the same time. Sort the attribute list according to the sorting characteristics to ensure that the order of the attribute list is consistent each time.
The above is the detailed content of saving data to the local area by c# reflection + custom features. For more information about saving data to the local area, please follow my other related articles!