static void PrepareInjection <T>( Mapping <T> mapping, IList <T> data, DbContext context, Type queryClass, ValuesInjectionMethod method) { var opts = new InterceptionOptions { QueryTableName = EFHelper.GetTableName(context, queryClass), ColumnNames = mapping.UserProperties.Keys.ToArray(), Data = data .Select(x => mapping.UserProperties.ToDictionary(y => y.Key, y => y.Value(x))) .ToList(), ContextType = context.GetType(), ValuesInjectMethod = (ValuesInjectionMethodInternal)method, KeyColumnName = mapping.KeyColumnName }; MemoryJoinerInterceptor.SetInterception(context, opts); }
/// <summary> /// Returns queryable wrapper for data /// </summary> /// <typeparam name="T"></typeparam> /// <param name="data"></param> /// <returns></returns> public static IQueryable <T> FromLocalList2 <T>(this DbContext context, IList <T> data, Type queryClass, ValuesInjectionMethod method) { var sb = new StringBuilder(100); var propMapping = allowedMappingDict.GetOrAdd(queryClass, (t) => MappingHelper.GetPropertyMappings(t)); var entityMapping = MappingHelper.GetEntityMapping <T>(context, queryClass, propMapping); var opts = new InterceptionOptions { QueryTableName = EFHelper.GetTableName(context, queryClass), ColumnNames = entityMapping.UserProperties.Keys.ToArray(), Data = data .Select(x => entityMapping.UserProperties.ToDictionary(y => y.Key, y => y.Value(x))) .ToList(), ContextType = context.GetType(), ValuesInjectMethod = (ValuesInjectionMethodInternal)method, KeyColumnName = entityMapping.KeyColumnName }; var connection = context.Database.GetDbConnection(); using (var command = connection.CreateCommand()) { var parameters = new List <DbParameter>(); MappingHelper.ComposeTableSql( sb, opts, command, parameters); var set = setMethod.MakeGenericMethod(queryClass) .Invoke(context, new object[] { }); var rawSqlString = new RawSqlString(sb.ToString()); var fromSql = fromSqlMethod .MakeGenericMethod(queryClass) .Invoke(null, new object[] { set, rawSqlString, parameters.ToArray() }); var middleResult = selectMethod.MakeGenericMethod(queryClass, typeof(T)) .Invoke(null, new object[] { fromSql, entityMapping.OutExpression }); var querySet = (IQueryable <T>)middleResult; return(querySet); } }
/// <summary> /// Returns queryable wrapper for data /// </summary> public static IQueryable <T> FromLocalList <T>(this DbContext context, IList <T> data, ValuesInjectionMethod method) { return(FromLocalList <T>(context, data, typeof(QueryModelClass), method)); }
/// <summary> /// Returns queryable wrapper for data /// </summary> /// <typeparam name="T"></typeparam> /// <param name="data"></param> /// <returns></returns> public static IQueryable <T> FromLocalList <T>(this DbContext context, IList <T> data, Type queryClass, ValuesInjectionMethod method) { if (MemoryJoinerInterceptor.IsInterceptionEnabled( new[] { context }, out InterceptionOptions opts)) { throw new InvalidOperationException( "Only one data set can be applied to single DbContext before actuall DB request is done"); } var propMapping = allowedMappingDict.GetOrAdd(queryClass, MappingHelper.GetPropertyMappings); var entityMapping = MappingHelper.GetEntityMapping <T>(context, queryClass, propMapping); var baseQuerySet = context.Set(queryClass); if (data.Any()) { PrepareInjection(entityMapping, data, context, queryClass, method); var middleResult = selectMethod.MakeGenericMethod(queryClass, typeof(T)) .Invoke(null, new object[] { baseQuerySet, entityMapping.OutExpression }); var querySet = (IQueryable <T>)middleResult; return(querySet); } else { var emptyQueryable = takeMethod.MakeGenericMethod(queryClass).Invoke(null, new object[] { baseQuerySet, 0 }); var middleResult = selectMethod.MakeGenericMethod(queryClass, typeof(T)) .Invoke(null, new object[] { emptyQueryable, entityMapping.OutExpression }); var querySet = (IQueryable <T>)middleResult; return(querySet); } }