|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Linq;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading;
- using System.Threading.Tasks;
-
- namespace RDH.Data
- {
- public static partial class SqlMapper
- {
- #region 扩展一对多查询
- #if !CSHARP30
- public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TReturn>(this IDbConnection cnn,
- string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TReturn> map,
- dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id",
- int? commandTimeout = null, CommandType? commandType = null)
- {
- return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, DontMap, DontMap, TReturn>(
- cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
- }
- public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TReturn>(this IDbConnection cnn,
- string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TReturn> map,
- dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id",
- int? commandTimeout = null, CommandType? commandType = null)
- {
- return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, DontMap, TReturn>(
- cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
- }
- public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(this IDbConnection cnn,
- string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn> map,
- dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id",
- int? commandTimeout = null, CommandType? commandType = null)
- {
- return MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
- cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType);
- }
- #endif
- static IEnumerable<TReturn> MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TReturn>(this IDbConnection cnn,
- string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType)
- {
- var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, DontMap, DontMap, TReturn>(
- cnn, sql, map, param, transaction, splitOn, commandTimeout, commandType, null, null);
- return buffered ? results.ToList() : results;
- }
- static IEnumerable<TReturn> MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TReturn>(this IDbConnection cnn,
- string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType)
- {
- var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, DontMap, TReturn>(cnn, sql, map, param, transaction, splitOn, commandTimeout, commandType, null, null);
- return buffered ? results.ToList() : results;
- }
- static IEnumerable<TReturn> MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(this IDbConnection cnn,
- string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType)
- {
- var results = MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
- cnn, sql, map, param, transaction, splitOn, commandTimeout, commandType, null, null);
- return buffered ? results.ToList() : results;
- }
- internal static IEnumerable<TReturn> MultiMapImpl<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
- this IDbConnection cnn, string sql, object map, object param, IDbTransaction transaction, string splitOn, int? commandTimeout,
- CommandType? commandType, IDataReader reader, Identity identity)
- {
- identity = identity ?? new Identity(sql, commandType, cnn, typeof(TFirst),
- (object)param == null ? null : ((object)param).GetType(),
- new[]
- {
- typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh), typeof(TEighth),
- typeof(TNinth), typeof(TTenth)
- });
- CacheInfo cinfo = GetCacheInfo(identity);
- IDbCommand ownedCommand = null;
- IDataReader ownedReader = null;
- try
- {
- if (reader == null)
- {
- ownedCommand = SetupCommand(cnn, transaction, sql, cinfo.ParamReader, (object)param, commandTimeout, commandType);
- ownedReader = ownedCommand.ExecuteReader();
- reader = ownedReader;
- }
- Func<IDataReader, object> deserializer = null;
- Func<IDataReader, object>[] otherDeserializers = null;
- Action cacheDeserializers = () =>
- {
- var deserializers = GenerateDeserializers(new Type[]
- {
- typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh), typeof(TEighth),
- typeof(TNinth), typeof(TTenth)
- }, splitOn, reader);
- deserializer = cinfo.Deserializer = deserializers[0];
- otherDeserializers = cinfo.OtherDeserializers = deserializers.Skip(1).ToArray();
- SetQueryCache(identity, cinfo);
- };
- if ((deserializer = cinfo.Deserializer) == null || (otherDeserializers = cinfo.OtherDeserializers) == null)
- {
- cacheDeserializers();
- }
- Func<IDataReader, TReturn> mapIt = GenerateMapper<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
- deserializer, otherDeserializers, map);
- if (mapIt != null)
- {
- while (reader.Read())
- {
- TReturn next;
- try
- {
- next = mapIt(reader);
- }
- catch (DataException)
- {
- cacheDeserializers();
- mapIt = GenerateMapper<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
- deserializer, otherDeserializers, map);
- next = mapIt(reader);
- }
- yield return next;
- }
- }
- }
- finally
- {
- try
- {
- if (ownedReader != null)
- {
- ownedReader.Dispose();
- }
- }
- finally
- {
- if (ownedCommand != null)
- {
- ownedCommand.Dispose();
- }
- }
- }
- }
- private static Func<IDataReader, TReturn> GenerateMapper<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>(
- Func<IDataReader, object> deserializer, Func<IDataReader, object>[] otherDeserializers, object map)
- {
- switch (otherDeserializers.Length)
- {
- case 1:
- return r => ((Func<TFirst, TSecond, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r));
- case 2:
- return r => ((Func<TFirst, TSecond, TThird, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r));
- case 3:
- return r => ((Func<TFirst, TSecond, TThird, TFourth, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r));
- #if !CSHARP30
- case 4:
- return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r));
- #endif
- case 5:
- return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r));
-
- case 6:
- return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>)map)((TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r), (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r), (TSeventh)otherDeserializers[5](r));
- case 7:
- return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TReturn>)map)(
- (TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r),
- (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r), (TSeventh)otherDeserializers[5](r), (TEighth)otherDeserializers[6](r));
- case 8:
- return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TReturn>)map)(
- (TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r),
- (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r), (TSeventh)otherDeserializers[5](r), (TEighth)otherDeserializers[6](r),
- (TNinth)otherDeserializers[7](r));
- case 9:
- return r => ((Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TEighth, TNinth, TTenth, TReturn>)map)(
- (TFirst)deserializer(r), (TSecond)otherDeserializers[0](r), (TThird)otherDeserializers[1](r), (TFourth)otherDeserializers[2](r),
- (TFifth)otherDeserializers[3](r), (TSixth)otherDeserializers[4](r), (TSeventh)otherDeserializers[5](r), (TEighth)otherDeserializers[6](r),
- (TNinth)otherDeserializers[7](r), (TTenth)otherDeserializers[8](r));
- default:
- throw new NotSupportedException();
- }
- }
- #endregion
- }
- }
|