private static void ModifyQuery(DbCommand command, InterceptionOptions opts) { var tableNamePosition = command.CommandText.IndexOf(opts.QueryTableName, StringComparison.Ordinal); if (tableNamePosition < 0) { return; } var nextSpace = command.CommandText.IndexOf(' ', tableNamePosition); var prevSpace = command.CommandText.LastIndexOf(' ', tableNamePosition); var tableFullName = command.CommandText.Substring(prevSpace + 1, nextSpace - prevSpace - 1); command.CommandText = command.CommandText.Replace(tableFullName, opts.DynamicTableName); var sb = new StringBuilder(100); sb.Append("WITH ").Append(opts.DynamicTableName).Append(" AS (").AppendLine(); MappingHelper.ComposeTableSql( sb, opts, command, command.Parameters); sb.AppendLine(); sb.AppendLine(")"); sb.Append(command.CommandText); command.CommandText = sb.ToString(); }
/// <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); } }
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); }
private static IServiceCollection Add <TService, TImplementation>(this IServiceCollection services, Func <ServiceLifetime, ServiceDescriptor> descriptorFactory, Action <IInterceptBy> configurator, ServiceLifetime lifetime) where TService : class where TImplementation : class, TService { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (configurator == null) { throw new ArgumentNullException(nameof(configurator)); } var interceptionOptions = new InterceptionOptions(); configurator.Invoke(interceptionOptions); interceptionOptions.Interceptors.ForEach(services.TryAddTransient); services.TryAdd(descriptorFactory(lifetime)); services.AddTransient(sp => { var interceptorInstances = interceptionOptions.Interceptors .Select(sp.GetRequiredService) .Cast <IInterceptor>() .ToArray(); var implementation = sp.GetRequiredService <TImplementation>(); var proxyFactory = new ProxyGenerator(); var proxyGenerationHook = new ConventionBasedProxyGenerationHook(interceptionOptions.Convention); var proxyGenerationOptions = new ProxyGenerationOptions(proxyGenerationHook); return(proxyFactory.CreateInterfaceProxyWithTarget <TService>(implementation, proxyGenerationOptions, interceptorInstances)); }); return(services); }
internal static bool IsInterceptionEnabled(IEnumerable <DbContext> contexts, out InterceptionOptions options) { options = null; using (var enumerator = contexts.GetEnumerator()) { if (!enumerator.MoveNext()) { return(false); } var firstOne = enumerator.Current; var result = firstOne != null && InterceptionOptions.TryGetValue(firstOne, out options) && !enumerator.MoveNext(); if (result) { InterceptionOptions.TryRemove(firstOne, out options); } return(result); } }
internal static void SetInterception(DbContext context, InterceptionOptions options) { InterceptionOptions[context] = options; }