/// <summary> /// 將自訂類型的 Properties 轉換成 Dictionary /// </summary> public static Dictionary <string, object> ToDictionary <T>(this T model, bool isComponentModel = false) { Dictionary <string, object> properties = new Dictionary <string, object>(); var props = isComponentModel ? CSharpHelper.GetMappedProperties <T>() : model.GetType().GetProperties(); foreach (PropertyInfo prop in props) { properties.Add( isComponentModel ? CSharpHelper.GetColumnName(prop) : prop.Name, prop.GetValue(model)); } return(properties); }
/// <summary> /// 將自訂類型的 Properties 轉換成 Dictionary, /// 轉換可依照 Attribute 來執行自定義的處理邏輯 /// </summary> public static Dictionary <string, object> ToDictionary <T, TAttr>(this T model, Func <object, IEnumerable <TAttr>, object> attrAdapter, bool isComponentModel = false) where TAttr : Attribute { Dictionary <string, object> properties = new Dictionary <string, object>(); var props = isComponentModel ? CSharpHelper.GetMappedProperties <T>() : model.GetType().GetProperties(); foreach (PropertyInfo prop in props) { string key = isComponentModel ? CSharpHelper.GetColumnName(prop) : prop.Name; object value = prop.GetValue(model); IEnumerable <TAttr> attrs = prop.GetCustomAttributes <TAttr>(); if (attrs.Any()) { value = attrAdapter(value, attrs); } properties.Add(key, value); } return(properties); }
/// <summary> /// 將 Dictionary 轉換成自訂 Class 的 object /// </summary> public static object ToTypeObject <T>(this Dictionary <string, T> dictionary, Type type, bool caseSensitive = false) { if (dictionary != null) { object model = type.Assembly.CreateInstance(type.FullName); var props = model.GetType().GetProperties(); var names = dictionary.Keys.ToArray(); foreach (PropertyInfo prop in props) { string columnName = CSharpHelper.GetColumnName(prop); int i = caseSensitive ? Array.IndexOf(names, columnName) : Array.IndexOf( names.Select(x => x.ToLower()).ToArray(), columnName.ToLower()); if (i >= 0 && dictionary[names[i]] != null && (dictionary[names[i]] as object) != DBNull.Value) { CSharpHelper.SetValueToProperty(model, prop, dictionary[names[i]]); } else { Dictionary <string, T> values = dictionary .Where(x => x.Key.StartsWith($"{columnName}.")) .ToDictionary( x => x.Key.Substring(columnName.Length + 1), x => x.Value); if (values.Any()) { CSharpHelper.SetValueToProperty(model, prop, values.ToTypeObject(prop.PropertyType)); } } } return(model); } return(null); }
/// <summary> /// 將 DataRow 的資料轉換成自訂 Class 的 object /// </summary> public static object ToTypeObject(this DataRow dr, Type type, bool caseSensitive = false) { if (dr != null) { object model = type.Assembly.CreateInstance(type.FullName); var props = type.GetProperties(); var names = caseSensitive ? dr.Table.Columns.Cast <DataColumn>().Select(x => x.ColumnName) : dr.Table.Columns.Cast <DataColumn>().Select(x => x.ColumnName.ToLower()); Dictionary <PropertyInfo, Dictionary <string, object> > innerClassProperties = new Dictionary <PropertyInfo, Dictionary <string, object> >(); foreach (PropertyInfo prop in props) { string columnName = CSharpHelper.GetColumnName(prop); if (names.Contains(caseSensitive ? columnName : columnName.ToLower()) && dr[columnName] != DBNull.Value) { CSharpHelper.SetValueToProperty(model, prop, dr[columnName]); } else { Dictionary <string, object> values = dr.ToDictionary() .Where(x => x.Key.StartsWith($"{columnName}.")) .ToDictionary( x => x.Key.Substring(columnName.Length + 1), x => x.Value); if (values.Any()) { CSharpHelper.SetValueToProperty(model, prop, values.ToTypeObject(prop.PropertyType)); } } } return(model); } return(null); }
/// <summary> /// 以 GenerateNode 生成代碼 /// </summary> public static async Task <string> GenerateAsync(this GenerateNode root) { string result = await root.ReadAsStringAsync(); if (string.IsNullOrWhiteSpace(result)) { return(null); } string paramLeft = root.Settings?.ParamLeft ?? "{{#"; // 參數起始的保留字 string paramRight = root.Settings?.ParamRight ?? "}}"; // 參數結束的保留字 string eachSeparator = root.Settings?.EachSeparator ?? ","; // 參數設定分隔符的保留字 string withDefault = root.Settings?.WithDefault ?? "|"; // 參數設定預設值的保留字 int searchIndex = 0; int paramStartIndex = result.IndexOf(paramLeft); while (paramStartIndex >= 0) { paramStartIndex = paramStartIndex + paramLeft.Length; int paramEndIndex = result.IndexOf(paramRight, paramStartIndex) - 1; int lineStartIndex = result.Substring(0, paramStartIndex).LastIndexOf("\n") + 1; int lineEndIndex = CSharpHelper.Using(result.IndexOf("\n", lineStartIndex + 1), x => x >= 0 ? x : result.Length) - 1; int separatorStartIndex = CSharpHelper.Using(result.Substring(0, paramEndIndex).IndexOf(eachSeparator, paramStartIndex), x => x >= 0 ? x + eachSeparator.Length : -1); int defaultStartIndex = CSharpHelper.Using(result.Substring(0, paramEndIndex).IndexOf(withDefault, Math.Max(paramStartIndex, separatorStartIndex)), x => x >= 0 ? x + withDefault.Length : -1); int separatorEndIndex = defaultStartIndex >= 0 ? defaultStartIndex - withDefault.Length - 1 : paramEndIndex; int defaultEndIndex = paramEndIndex; int keyStartIndex = paramStartIndex; int keyEndIndex = separatorStartIndex >= 0 ? separatorStartIndex - eachSeparator.Length - 1 : defaultStartIndex >= 0 ? defaultStartIndex - withDefault.Length - 1 : paramEndIndex; if (paramStartIndex < paramEndIndex && paramEndIndex < lineEndIndex && separatorStartIndex < paramEndIndex && defaultStartIndex < paramEndIndex) { string prefix = result.Substring(lineStartIndex, paramStartIndex - paramLeft.Length - lineStartIndex); string suffix = result.Substring(paramEndIndex + paramRight.Length + 1, lineEndIndex - (paramEndIndex + paramRight.Length)); string key = result.Substring(keyStartIndex, keyEndIndex - keyStartIndex + 1).Trim(); string value = ""; string param = result.Substring(paramStartIndex, paramEndIndex - paramStartIndex + 1); string separator = separatorStartIndex >= 0 ? result.Substring(separatorStartIndex, separatorEndIndex - separatorStartIndex + 1).Trim() : ""; string @default = defaultStartIndex >= 0 ? result.Substring(defaultStartIndex, defaultEndIndex - defaultStartIndex + 1).Trim() : ""; foreach (var synonym in GenerateSynonyms) { separator = separator.Replace(synonym.Key, synonym.Value); @default = @default.Replace(synonym.Key, synonym.Value); } #region Apply if (string.IsNullOrWhiteSpace(key) == false) { if (root.ApplyParameters.Any(x => x.ApplyKey == key)) { value = string.Join( separator, await Task.WhenAll( root.ApplyParameters .Where(x => x.ApplyKey == key) .Select(async node => { if (string.IsNullOrWhiteSpace(node.ApplyApi) == false) { return(await GenerateAsync(node)); } return(await node.ReadAsStringAsync()); }))); } if (string.IsNullOrWhiteSpace(value)) { value = @default; } if (string.IsNullOrWhiteSpace(prefix)) { value = value.Replace("\n", $"\n{prefix}"); } if (string.IsNullOrWhiteSpace(value) && string.IsNullOrWhiteSpace(prefix) && string.IsNullOrWhiteSpace(suffix)) { if (lineEndIndex + 2 < result.Length) { result = $"{result.Substring(0, Math.Max(lineStartIndex - 1, 0))}{result.Substring(lineEndIndex + 2)}"; searchIndex = lineStartIndex; } else { result = $"{result.Substring(0, Math.Max(lineStartIndex - 1, 0))}"; searchIndex = -1; } } else { result = $"{result.Substring(0, paramStartIndex - paramLeft.Length)}{value}{result.Substring(paramEndIndex + paramRight.Length + 1)}"; searchIndex = paramStartIndex - paramLeft.Length + value.Length; } } else { searchIndex = paramStartIndex + paramRight.Length; } #endregion } else { searchIndex = paramStartIndex + paramRight.Length; } paramStartIndex = searchIndex >= 0 ? result.IndexOf(paramLeft, searchIndex) : -1; } return(result); }