public static SqlParameter ConstructParameter <T>(IEnumerable <T> records, string variableName) { if (records == null || string.IsNullOrEmpty(variableName)) { return(null); } SqlParameter parameter = null; Type objectType = typeof(T); TableTypeAttribute tableTypeAttribute = GetSpecifiedObject <TableTypeAttribute>(objectType.GetCustomAttributes(typeof(TableTypeAttribute), false)); if (tableTypeAttribute != null) { DataTable dt = new DataTable(tableTypeAttribute.TableName); Dictionary <string, PropertyInfo> colNamePropertyMapping = new Dictionary <string, PropertyInfo>(); Dictionary <string, string> colNameMethodMapping = new Dictionary <string, string>(); PropertyInfo[] propertyInfos = objectType.GetProperties(); foreach (PropertyInfo propertyInfo in propertyInfos) { ColumnAttribute columnAttribute = GetSpecifiedObject <ColumnAttribute>(propertyInfo.GetCustomAttributes(typeof(ColumnAttribute), false)); if (columnAttribute != null) { dt.Columns.Add(new DataColumn(columnAttribute.ColumnName, columnAttribute.CustomType ?? propertyInfo.PropertyType)); colNamePropertyMapping.Add(columnAttribute.ColumnName, propertyInfo); if (!string.IsNullOrEmpty(columnAttribute.FormatMethodName)) { colNameMethodMapping.Add(columnAttribute.ColumnName, columnAttribute.FormatMethodName); } } } foreach (T record in records) { DataRow row = dt.NewRow(); foreach (var colNameProperty in colNamePropertyMapping) { if (colNameMethodMapping.ContainsKey(colNameProperty.Key)) { object target = colNameProperty.Value.GetValue(record); row[colNameProperty.Key] = target.GetType().GetMethod(colNameMethodMapping[colNameProperty.Key], Type.EmptyTypes).Invoke(target, null); } else { row[colNameProperty.Key] = colNameProperty.Value.GetValue(record); } } dt.Rows.Add(row); } dt.AcceptChanges(); parameter = new SqlParameter(variableName, dt); parameter.SqlDbType = SqlDbType.Structured; parameter.TypeName = tableTypeAttribute.TableName; } return(parameter); }
/// <summary> /// Converts any data into a DataTable as long as its marked with the TableTypeAttribute attribute /// </summary> /// <typeparam name="T">the source type to convert into a DataTable object</typeparam> /// <param name="data">the structured data to convert into a DataTable</param> /// <param name="tableTypeName">the tableType Name that is declared in the database</param> /// <returns>a DataTable containing the provided data</returns> public static DataTable ToDataTable(this IEnumerable data, out string tableTypeName) { if (data == null) { throw new ArgumentNullException("data"); } object[] arrayObject = data as object[] ?? Enumerable.Cast <object>(data).ToArray(); Type t = arrayObject.First().GetType(); if (t == typeof(DynamicResult)) { throw new InvalidOperationException("Wrong usage of ToDataTable. Please use the overload ToDataTable(IEnumerable<DynamicResult>)"); } DataTable retVal = new DataTable(); TableTypeAttribute attr = (TableTypeAttribute)Attribute.GetCustomAttribute(t, typeof(TableTypeAttribute)); if (attr == null) { throw new ArgumentException( "the passed array does not contain data that is marked with a TableTypeAttribute", "data"); } tableTypeName = attr.TableTypeName ?? t.Name; var properties = (from n in t.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty) select new { Property = n, Attribute = (TypeColumnAttribute)Attribute.GetCustomAttribute(n, typeof(TypeColumnAttribute), true) }); if (attr.Layout == TableTypeLayout.Explicit) { properties = (from n in properties orderby n.Attribute.OrdinalPosition select n); } var propArr = properties.ToArray(); propArr.ForEach( n => retVal.Columns.Add(n.Attribute != null ? (n.Attribute.ColumnName ?? n.Property.Name) : n.Property.Name, GetTableType(n.Attribute != null ? (n.Attribute.ColumnType ?? n.Property.PropertyType) : n.Property.PropertyType))); (from n in arrayObject select(from u in propArr select new { Value = u.Property.GetValue(n, null), Name = u.Attribute != null ? (u.Attribute.ColumnName ?? u.Property.Name) : u.Property.Name, } )).ForEach(n => { DataRow row = retVal.NewRow(); n.ForEach(d => row[d.Name] = d.Value ?? DBNull.Value); retVal.Rows.Add(row); }); return(retVal); }