/// <summary> /// Converts a sequence of <paramref name="items"/> into a sequence of <see cref="SqlDataRecord"/> using the supplied <paramref name="metaData"/> /// </summary> internal static IEnumerable <SqlDataRecord> ToDataRecords <T>(this IEnumerable <T> items, SqlMetaData[] metaData) { Contract.Requires(items != null); Contract.Requires(metaData != null); Contract.Requires(metaData.Length > 0); var key = new TypeAndMetaData(typeof(T), metaData); var map = (Func <SqlMetaData[], T, SqlDataRecord>)GetOrAddFunc(key, typeof(T)); return(items.Select(item => map(metaData, item))); }
/// <summary> /// Converts a sequence of <paramref name="items"/> into a <see cref="SqlTable"/> containing a sequence of <see cref="SqlDataRecord"/> using the supplied <paramref name="metaData"/> /// </summary> /// <remarks><paramref name="extraAction"/> can be used to set additional values on each <see cref="SqlDataRecord"/></remarks> public static SqlTable ToSqlTable <T>(this IEnumerable <T> items, SqlTableType type, Action <SqlDataRecord, T> extraAction) { Contract.Requires(items != null); Contract.Requires(type.Columns != null); Contract.Requires(!string.IsNullOrWhiteSpace(type.Name)); Contract.Ensures(Contract.Result <IEnumerable <SqlDataRecord> >() != null); var key = new TypeAndMetaData(typeof(T), type.Columns); var map = (Func <SqlMetaData[], T, SqlDataRecord>)GetOrAddFunc(key, typeof(T)); if (items.Any()) { return(new SqlTable(type.Name, ConvertItemsToRecords(items, type.Columns, map, extraAction))); } else { return(new SqlTable(type.Name, null)); // SQL will throw and exception if you try to pass an empty enumeration } }
static Delegate GetOrAddFunc(TypeAndMetaData key, Type typeT) => Methods.GetOrAdd(key, data => CreateMappingFunc(typeT, data.MetaData));