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);
            }
        }