English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Spesso ci si imbatte in questo tipo di situazione, quando rispondiamo alle richieste dei clienti dobbiamo trattare i dati, ad esempio, i dati nel database sono di tipo int, che possono rappresentare un'enumerazione o altri significati logici (un tale disegno del database potrebbe essere considerato dagli aspetti della sicurezza dei dati, della quantità di archiviazione, ecc.), ma quando li mostriamo al cliente devono avere il loro significato specifico.
In questo momento, il nostro modo di trattare è generalmente il metodo 2, se la logica non è complessa e è unica, possiamo gestire direttamente la sorgente dei dati modificando la query SQL, in questo caso non è necessario trattare nulla nel codice.
Ma se la logica è leggermente più complessa o ci sono molte ramificazioni di giudizio, dobbiamo trattarla dal punto di vista del codice. Per un singolo oggetto va bene, ma per più oggetti come una list<T>, dobbiamo ciclare sui campi di un oggetto per XXX.
Di conseguenza, è emerso questo DTO, Arg, l'oggetto intermedio, naturalmente, mi piace molto questo design, ma a volte mi permetto di essere pigro e non scrivere (molto spesso scrivo generatori di codice in batch), come durante i test, quando accetto incarichi privati, quando faccio dimostrazioni, solo per presentare rapidamente l'effetto desiderato, non mi dispiace nemmeno essere fastidioso. Sì, diresti che ci sono molte librerie di mappatura sul mercato, come automap, tinymap, persino le caratteristiche dinamiche di json.net, ci sono molti metodi, ma usare una ruota grande per fare un lavoro così piccolo, penso che non valga la pena. E più grande diventa la ruota, più cose deve fare, non voglio complicare così tanto, sì, è così, l'ho scritto.
Il codice specifico viene inserito di seguito, se capisci, sarà molto facile espandere o modificare per ottenere l'effetto desiderato.
using System.Dynamic; using System.Reflection; using System.Collections.Concurrent; private static readonly ConcurrentDictionary<RuntimeTypeHandle, PropertyInfo[]> DynamicObjectProperties = new ConcurrentDictionary<RuntimeTypeHandle, PropertyInfo[]>(); private IDictionary<string, Object> ToDynamicResult<T>(T classobj, Func<string, object, object> injectAct) where T : IInjectClass, new() { var type = typeof(T); var key = type.TypeHandle; var dynamicResult = new ExpandoObject() as IDictionary<string, Object>; PropertyInfo[] queryPts = null; DynamicObjectProperties.TryGetValue(key, out queryPts); if (queryPts == null) { queryPts = type.GetProperties(); DynamicObjectProperties.TryAdd(key, queryPts); } foreach (var p in queryPts) { var attributes = p.GetCustomAttributes(typeof(IngorePropertyAttribute), true); var columnMapping = attributes.FirstOrDefault(); if (columnMapping != null) continue; var _name = p.Name; var _value = p.GetValue(classobj, null); object _tempvalue = _value; if (injectAct != null) _tempvalue = injectAct.Invoke(_name, _value); //var value = Convert.ChangeType(value,typeof(string)); dynamicResult.Add(p.Name, _tempvalue); } return dynamicResult; } /// <summary> /// Interfaccia oggetto supportato per l'output dinamico /// </summary> public interface IInjectClass { } /// <summary> /// Ignora le proprietà marcate con questo segno durante l'output dinamico /// </summary> public class IngorePropertyAttribute : Attribute { }
Di seguito testiamo un:
public class kk : IInjectClass { public string aa { get; set; } public int bb { get; set; } [IgnoraProprietà] public bool cc { get; set; } public DateTime dd { get; set; } }kk ist = new kk(); ist.aa = "aaa"; ist.bb = 123; ist.cc = false; ist.dd = DateTime.Now; var tt = ToDynamicResult<kk>(ist, (k, v) => { if (k != "aa") return v; return v + "(cambiato)"; }); var json = Tools.JsonUtils.JsonSerializer(tt); json = json + "<br /><br />" + Tools.JsonUtils.JsonSerializer(ToDynamicResult<kk>( new kk { aa = "test", bb = 789; cc = true; dd = DateTime.Now.AddDays(2); }, null)); Response.Write(json);
Puoi ricostruire le caratteristiche con parametri o modificare l'oggetto injectAct, cambiandolo per adattarlo a te
Scrivo un test, è meglio diventare un albero di espressioni, metto il codice prima
using System; using System.Linq; using System.Dynamic; using System.Reflection; using System.Linq.Expressions; using System.Collections.Generic; using System.Collections.Concurrent; namespace Tools { public class Class2Map { private static readonly ConcurrentDictionary<RuntimeTypeHandle, PropertyInfo[]> DynamicObjectProperties = new ConcurrentDictionary<RuntimeTypeHandle, PropertyInfo[]>(); private static PropertyInfo[] GetObjectProperties<T>() { var type = typeof(T); var key = type.TypeHandle; PropertyInfo[] queryPts = null; DynamicObjectProperties.TryGetValue(key, out queryPts); if (queryPts == null) { queryPts = type.GetProperties(); DynamicObjectProperties.TryAdd(key, queryPts); } return queryPts; } /// <summary> /// Mappatura di oggetto singolo /// </summary> /// <typeparam name="T">Tipo</typeparam> /// <param name="source">Esempio</param> /// <param name="injectAct">Set di metodi di mappatura</param> /// <returns>Oggetto dinamico mappato</returns> public static IDictionary<string, Object> DynamicResult<T>(T source, params MapCondition[] injectAct)//where T : ICustomMap { var queryPts = GetObjectProperties<T>(); var dynamicResult = new ExpandoObject() as IDictionary<string, Object>; foreach (var p in queryPts) { var attributes = p.GetCustomAttributes(typeof(IngoreProperty), true); if (attributes.FirstOrDefault() != null) continue; var _name = p.Name; //Nome dell'attributo originale var _value = p.GetValue(source, null); //Valore dell'attributo originale object _resultvalue = _value; //Valore di mappatura finale if (injectAct != null) { string _tempname = null; var condition = injectAct.FirstOrDefault(x => x.Orginal == _name); if (CheckChangeInfo(condition, out _tempname)) { _resultvalue = condition.fn.Invoke(_value); dynamicResult.Add(_tempname ?? _name, _resultvalue); continue; } } //var value = Convert.ChangeType(value,typeof(string)); dynamicResult.Add(_name, _resultvalue); } return dynamicResult; } /// <summary> /// 合并2个对象 /// </summary> /// <typeparam name="TSource">对象1类型</typeparam> /// <typeparam name="TTarget">对象2类型</typeparam> /// <param name="s">对象1实例</param> /// <param name="t">对象2实例</param> /// <returns>合并后的动态对象</returns> public static IDictionary<string, Object> MergerObject<TSource, TTarget>(TSource s, TTarget t) { var targetPts = GetObjectProperties<TSource>(); PropertyInfo[] mergerPts = null; var _type = t.GetType(); mergerPts = _type.Name.Contains("<>") ? _type.GetProperties() : GetObjectProperties<TTarget>(); var dynamicResult = new ExpandoObject() as IDictionary<string, Object>; foreach (var p in targetPts) { var attributes = p.GetCustomAttributes(typeof(IngoreProperty), true); if (attributes.FirstOrDefault() != null) continue; dynamicResult.Add(p.Name, p.GetValue(s, null)); } foreach (var p in mergerPts) { var attributes = p.GetCustomAttributes(typeof(IngoreProperty), true); if (attributes.FirstOrDefault() != null) continue; dynamicResult.Add(p.Name, p.GetValue(t, null)); } return dynamicResult; } /// <summary> /// 合并2个对象 /// </summary> /// <typeparam name="TSource">对象1类型</typeparam> /// <typeparam name="TTarget">对象2类型</typeparam> /// <param name="s">对象1实例</param> /// <param name="t">对象2实例</param> /// <returns>合并后的动态对象</returns> public static List<IDictionary<string, Object>> MergerListObject<TSource, TTarget>(List<TSource> s, TTarget t) { var targetPts = GetObjectProperties<TSource>(); PropertyInfo[] mergerPts = null; var _type = t.GetType(); mergerPts = _type.Name.Contains("<>") ? _type.GetProperties() : GetObjectProperties<TTarget>(); var result = new List<IDictionary<string, Object>>(); s.ForEach(x => { var dynamicResult = new ExpandoObject() as IDictionary<string, Object>; foreach (var p in targetPts) { var attributes = p.GetCustomAttributes(typeof(IngoreProperty), true); if (attributes.FirstOrDefault() != null) continue; dynamicResult.Add(p.Name, p.GetValue(x, null)); } foreach (var p in mergerPts) { var attributes = p.GetCustomAttributes(typeof(IngoreProperty), true); if (attributes.FirstOrDefault() != null) continue; dynamicResult.Add(p.Name, p.GetValue(t, null)); } result.Add(dynamicResult); }); return result; } private static bool CheckChangeInfo(MapCondition condition, out string name) { name = null; bool result = condition != null && condition.fn != null && !string.IsNullOrWhiteSpace(condition.Orginal);//&& //!string.IsNullOrWhiteSpace(condition.NewName); if (result) { var temp = condition.NewName; name = (string.IsNullOrWhiteSpace(temp) || temp.Trim().Length == 0) ? null : temp; } return result; } } }
Testa un po':
List<KeyValue> kk = new List<KeyValue> { new KeyValue{key="aaa", value="111"}, new KeyValue{key="bbb", value="222"}, new KeyValue{key="ccc", value="333"}, new KeyValue{key="ddd", value="444"}, }; var result = Class2Map.MergerListObject<KeyValue, dynamic>(kk, new { p = "jon test" }); var json = JsonUtils.JsonSerializer(result); Response.Write(json);
L'output è come segue:
[{"key":"aaa","value":"111","p":"jon test"},{"key":"bbb","value":"222","p":"jon test"},{"key":"ccc","value":"333","p":"jon test"},{"key":"ddd","value":"444","p":"jon test"}] var result = Class2Map.MergerObject<KeyValue, dynamic>( new KeyValue { key = "aaa", value = "111" }, new { p = "jon test" } ); var json = JsonUtils.JsonSerializer(result); Response.Write(json);
L'output è come segue:
{"key": "aaa", "value": "111", "p": "jon test" }
Questa guida sull'oggetto dinamico C# e la creazione di oggetti dinamici, la combinazione di due oggetti, l'istanza Map è tutto ciò che condivido con voi, spero possa essere di riferimento per voi, e spero che tutti possano sostenere il tutorial urlaio.