DataRow is converted to generic, and the query data is directly converted to an object using reflection.
Preface: This method converts DataRow into an object using reflection. Because reflection SetValue is said to be of poor performance, let's just look at it.
Using System; using System. collections. generic; using System. data; using System. linq; using System. reflection; using System. text; namespace WangSql. DBUtility {public class DataMapHelper {private enum ModelType {Value, String, Object, Reference} private static ModelType GetModelType (Type modelType) {if (modelType. isValueType) // value type {return ModelType. value;} else if (modelType = typeof (string) // reference type Special Type processing {return ModelType. string;} else if (modelType = typeof (object) // handle special types of reference {return ModelType. object;} else // reference type {return ModelType. reference ;}} public static List <T> DataTableToList <T> (DataTable table) {List <T> list = new List <T> (); foreach (DataRow item in table. rows) {list. add (DataRowToModel <T> (item);} return list;} public static T DataRowToModel <T> (DataRow row) {T model; Type type = typeof (T); ModelType modelType = GetModelType (type); switch (modelType) {case ModelType. value: // Value type {model = default (T); if (row [0]! = Null) model = (T) row [0];} break; case ModelType. string: // reference type c # string is also treated as value type {model = default (T); if (row [0]! = Null) model = (T) row [0];} break; case ModelType. object: // The reference type directly returns the value of the first column of the First row {model = default (T); if (row [0]! = Null) model = (T) row [0];} break; case ModelType. reference: // Reference type {model = System. activator. createInstance <T> (); // The reference type must be instantiated for the generic type # region MyRegion // obtain the attribute PropertyInfo [] modelPropertyInfos = type in the model. getProperties (); // traverse each attribute of the model and assign a value to the column foreach (PropertyInfo pi in modelPropertyInfos) corresponding to DataRow {// obtain the attribute name String name = pi. name; if (row. table. columns. contains (name) {// non-generic if (! Pi. propertyType. isGenericType) {if (pi. propertyType. isEnum) {pi. setValue (model, row [name], null);} else {pi. setValue (model, string. isNullOrEmpty (row [name]. toString ())? Null: Convert. changeType (row [name], pi. propertyType), null) ;}/// generic Nullable <> else {Type genericTypeDefinition = pi. propertyType. getGenericTypeDefinition (); // if (genericTypeDefinition = typeof (Nullable <>) can be null )) {// return the basic type parameter pi of the specified type that can be null. setValue (model, string. isNullOrEmpty (row [name]. toString ())? Null: Convert. changeType (row [name], Nullable. getUnderlyingType (pi. propertyType), null) ;}}# endregion} break; default: model = default (T); break;} return model ;}}}
After that,
1. You can use the cache to improve the performance.
After each typeof (T), store the object-related information (such as generic attributes) and read it from the cache the next time.
2. Improve SetValue.
You can assign values to generic delegates.
3. Use Emit