示例#1
0
        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);
        }