gpt4 book ai didi

【源码解读(一)】EFCORE源码解读之创建DBContext查询拦截

转载 作者:我是一只小鸟 更新时间:2023-10-13 23:02:50 33 4
gpt4 key购买 nike

引言

    在网上很少看到有关于系统讲解EFCore源码的,可能大概也许是因为EFCore的源码总体是没有asp.net web的源码流程清晰,正如群友所说,EFCore的源码大致看起来有点凌乱,与其说凌乱,不如说是没有一个好的方向;然后昨天在群里有一个朋友再说,EfCore的拦截器如何注入Web的服务,以及EfCore如何自定义查询,我就看了一下EfCore的源码,在此之前我针对asp.net web 做了一个源码解读,有兴趣的朋友可以看前面的文章,也给别人说过啥时候讲解一下efcore的源码,刚好借助这么一个机会,讲一讲EfCore的源码,本篇文章作为一个开端,会呈现一下几点 。

    一:首先是AddDbContext里面做了什么.

    二:DbContext的构造函数里面做了那些事情.

    三:如何在EfCore的服务中获取到Web注入的服务的方式之一.

    四:拦截查询的几种方式.

    五:使用缓存查询方法提升性能.

    六:如何托管EFCORE的IOC容器(和Web的IOC使用同一个) 。

    以上作为本篇文章的所有内容,接下来,我们来开始讲解源码,动手实践.

AddDbContext

    EfCore提供了AddDbContext,AddDbContextFactory,AddDbContextPool,AddPooledDbContextFactory这几种扩展方法,我们会依次讲解,首先会讲解AddDbContext,后续的文章会依次讲解其余的方法。话不多说,上源码。下面是AddDbContext的源码,提供了多种方法,但是最终都会调用到这里,第一个参数是一个设置OptionBuilder的委托,传入了ServiceProvider和OptionBuilder,第二,三个分别是DbContext和DBContextOption的生命周期.

    在下面的代码,刚开始判断了如果DBContext的生命周期是单例,要将Option的生命周期也设置为单例,如果不设置为单例,就会出现错误,这个错误在之前讲解IOC的文章中,我记得也提到过,接下来判断设置Option的委托是否为null,如果不为null,那DBContext的构造函数是必须要有一个参数,所以下面调用了一个方法CheckContextConstructors.

                          
                            public
                          
                          
                            static
                          
                           IServiceCollection AddDbContext<TContextService, TContextImplementation>
                          
                            (
     
                          
                          
                            this
                          
                          
                             IServiceCollection serviceCollection,
     Action
                          
                          <IServiceProvider, DbContextOptionsBuilder>?
                          
                             optionsAction,
     ServiceLifetime contextLifetime 
                          
                          =
                          
                             ServiceLifetime.Scoped,
     ServiceLifetime optionsLifetime 
                          
                          =
                          
                             ServiceLifetime.Scoped)
     
                          
                          
                            where
                          
                          
                             TContextImplementation : DbContext, TContextService
 {
     
                          
                          
                            if
                          
                           (contextLifetime ==
                          
                             ServiceLifetime.Singleton)
     {
         optionsLifetime 
                          
                          =
                          
                             ServiceLifetime.Singleton;
     }

     
                          
                          
                            if
                          
                           (optionsAction != 
                          
                            null
                          
                          
                            )
     {
         CheckContextConstructors
                          
                          <TContextImplementation>
                          
                            ();
     }

     AddCoreServices
                          
                          <TContextImplementation>
                          
                            (serviceCollection, optionsAction, optionsLifetime);

     
                          
                          
                            if
                          
                           (serviceCollection.Any(d => d.ServiceType == 
                          
                            typeof
                          
                          (IDbContextFactorySource<TContextImplementation>
                          
                            )))
     {
         
                          
                          
                            //
                          
                          
                             Override registration made by AddDbContextFactory
                          
                          
                            var
                          
                           serviceDescriptor = serviceCollection.FirstOrDefault(d => d.ServiceType == 
                          
                            typeof
                          
                          
                            (TContextImplementation));
         
                          
                          
                            if
                          
                           (serviceDescriptor != 
                          
                            null
                          
                          
                            )
         {
             serviceCollection.Remove(serviceDescriptor);
         }
     }

     serviceCollection.TryAdd(
                          
                          
                            new
                          
                           ServiceDescriptor(
                          
                            typeof
                          
                          (TContextService), 
                          
                            typeof
                          
                          
                            (TContextImplementation), contextLifetime));

     
                          
                          
                            if
                          
                           (
                          
                            typeof
                          
                          (TContextService) != 
                          
                            typeof
                          
                          
                            (TContextImplementation))
     {
         serviceCollection.TryAdd(
             
                          
                          
                            new
                          
                          
                             ServiceDescriptor(
                 
                          
                          
                            typeof
                          
                          
                            (TContextImplementation),
                 p 
                          
                          => (TContextImplementation)p.GetService<TContextService>()!
                          
                            ,
                 contextLifetime));
     }

     
                          
                          
                            return
                          
                          
                             serviceCollection;
 }
                            

                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                           CheckContextConstructors<TContext>
                          
                            ()
     
                          
                          
                            where
                          
                          
                             TContext : DbContext
 {
     
                          
                          
                            var
                          
                           declaredConstructors = 
                          
                            typeof
                          
                          
                            (TContext).GetTypeInfo().DeclaredConstructors.ToList();
     
                          
                          
                            if
                          
                           (declaredConstructors.Count == 
                          
                            1
                          
                          
         && declaredConstructors[
                          
                            0
                          
                          ].GetParameters().Length == 
                          
                            0
                          
                          
                            )
     {
         
                          
                          
                            throw
                          
                          
                            new
                          
                           ArgumentException(CoreStrings.DbContextMissingConstructor(
                          
                            typeof
                          
                          
                            (TContext).ShortDisplayName()));
     }
 }
                          
                        

    在CheckContextConstructors,我们看到反射去获取DBContext的继承类,查找构造函数,并且参数如果是0就会报异常。接下来在往下走,调用了一个AddCoreServices的方法,在这个方法里,我们是将DBContextOptions的泛型和非泛型注入到容器里面去,其中有一个CreateDbContextOptions的方法,里面去new了一个DbContextOptionsBuilder类,然后调用了一个UseApplicationServiceProvider方法, 。

                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                           AddCoreServices<TContextImplementation>
                          
                            (
        IServiceCollection serviceCollection,
        Action
                          
                          <IServiceProvider, DbContextOptionsBuilder>?
                          
                             optionsAction,
        ServiceLifetime optionsLifetime)
        
                          
                          
                            where
                          
                          
                             TContextImplementation : DbContext
    {
        serviceCollection.TryAdd(
            
                          
                          
                            new
                          
                          
                             ServiceDescriptor(
                
                          
                          
                            typeof
                          
                          (DbContextOptions<TContextImplementation>
                          
                            ),
                p 
                          
                          => CreateDbContextOptions<TContextImplementation>
                          
                            (p, optionsAction),
                optionsLifetime));

        serviceCollection.Add(
            
                          
                          
                            new
                          
                          
                             ServiceDescriptor(
                
                          
                          
                            typeof
                          
                          
                            (DbContextOptions),
                p 
                          
                          => p.GetRequiredService<DbContextOptions<TContextImplementation>>
                          
                            (),
                optionsLifetime));
    }

    
                          
                          
                            private
                          
                          
                            static
                          
                           DbContextOptions<TContext> CreateDbContextOptions<TContext>
                          
                            (
        IServiceProvider applicationServiceProvider,
        Action
                          
                          <IServiceProvider, DbContextOptionsBuilder>?
                          
                             optionsAction)
        
                          
                          
                            where
                          
                          
                             TContext : DbContext
    {
        
                          
                          
                            var
                          
                           builder = 
                          
                            new
                          
                           DbContextOptionsBuilder<TContext>
                          
                            (
            
                          
                          
                            new
                          
                           DbContextOptions<TContext>(
                          
                            new
                          
                           Dictionary<Type, IDbContextOptionsExtension>
                          
                            ()));

        builder.UseApplicationServiceProvider(applicationServiceProvider);

        optionsAction
                          
                          ?
                          
                            .Invoke(applicationServiceProvider, builder);

        
                          
                          
                            return
                          
                          
                             builder.Options;
    }
                          
                        

    下面是一个UseApplicationServiceProvider的调用链,最终调用到了WithApplicationServiceProvider方法,可以看到是返回了一个CoreOptionsExtension,最终调用WithOptions添加到了DbContextOptionsBuilder里面去,上面的代码中,我们new了一个DbContextOptionsBuilder,里面传入了一个DbContextOptions,构造函数传入了new Dictionary<Type,IDbContextOptionsExtension>(),最终我们的CoreOptionsExtension会添加到我们传入的这个字典里,用来保存所有的IDbContextOptionsExtension,这个接口可以理解为,数据库Options的扩展,接口定义如下,Info是关于扩展的一些元数据信息,ApplyService方法,参数是一个IServiceCollection,这个方法是我们将我们要注入的服务注入到这个里面去,因为EfCore的IOC和Web的IOC是区分开的,所以使用了不同的IServiceCollection,虽然提供了UseApplicationServiceProvider和UseInternalServiceProvider方法,实际上并不能实现IOC接管,设计实在是鸡肋,待会到了DbContext的构造函数中我们会看到为什么说鸡肋。Validate方法则是验证当前扩展,例如你得这个实现里面有一些参数,是必须要配置,或者配置有一个规则,我们在这里验证我们的配置或者规则是否符合我们需要的数据,如果不符合,在这里可以直接抛出异常.

    回到CreateDbContextOptions,此时我们可以确保我们的Option的Extension里面是有一个CoreOptionsExtension,接下来,判断有没有设置OptionsBuilder的委托,调用然后返回到AddDbContext.

                          
                            public
                          
                          
                            new
                          
                          
                            virtual
                          
                           DbContextOptionsBuilder<TContext> UseApplicationServiceProvider(IServiceProvider?
                          
                             serviceProvider)
     
                          
                          => (DbContextOptionsBuilder<TContext>)
                          
                            base
                          
                          
                            .UseApplicationServiceProvider(serviceProvider);
  
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbContextOptionsBuilder UseApplicationServiceProvider(IServiceProvider?
                          
                             serviceProvider)
      
                          
                          => WithOption(e =>
                          
                             e.WithApplicationServiceProvider(serviceProvider));
    
                          
                          
                            public
                          
                          
                            virtual
                          
                           CoreOptionsExtension WithApplicationServiceProvider(IServiceProvider?
                          
                             applicationServiceProvider)
    {
        
                          
                          
                            var
                          
                           clone =
                          
                             Clone();

        clone._applicationServiceProvider 
                          
                          =
                          
                             applicationServiceProvider;

        
                          
                          
                            return
                          
                          
                             clone;
    }
                          
                        
                          
                            private
                          
                           DbContextOptionsBuilder WithOption(Func<CoreOptionsExtension, CoreOptionsExtension>
                          
                             withFunc)
  {
      ((IDbContextOptionsBuilderInfrastructure)
                          
                          
                            this
                          
                          
                            ).AddOrUpdateExtension(
          withFunc(Options.FindExtension
                          
                          <CoreOptionsExtension>() ?? 
                          
                            new
                          
                          
                             CoreOptionsExtension()));

      
                          
                          
                            return
                          
                          
                            this
                          
                          
                            ;
  }
                          
                        
                          
                            public
                          
                          
                            interface
                          
                          
                             IDbContextOptionsExtension
{
    
                          
                          
                            ///
                          
                          
                            <summary>
                          
                          
                            ///
                          
                          
                                 Information/metadata about the extension.
    
                          
                          
                            ///
                          
                          
                            </summary>
                          
                          
    DbContextOptionsExtensionInfo Info { 
                          
                            get
                          
                          
                            ; }

    
                          
                          
                            ///
                          
                          
                            <summary>
                          
                          
                            ///
                          
                          
                                 Adds the services required to make the selected options work. This is used when there
    
                          
                          
                            ///
                          
                          
                                 is no external 
                          
                          
                            <see cref="IServiceProvider" />
                          
                          
                             and EF is maintaining its own service
    
                          
                          
                            ///
                          
                          
                                 provider internally. This allows database providers (and other extensions) to register their
    
                          
                          
                            ///
                          
                          
                                 required services when EF is creating an service provider.
    
                          
                          
                            ///
                          
                          
                            </summary>
                          
                          
                            ///
                          
                          
                            <param name="services">
                          
                          
                            The collection to add services to.
                          
                          
                            </param>
                          
                          
                            void
                          
                          
                             ApplyServices(IServiceCollection services);

    
                          
                          
                            ///
                          
                          
                            <summary>
                          
                          
                            ///
                          
                          
                                 Gives the extension a chance to validate that all options in the extension are valid.
    
                          
                          
                            ///
                          
                          
                                 Most extensions do not have invalid combinations and so this will be a no-op.
    
                          
                          
                            ///
                          
                          
                                 If options are invalid, then an exception should be thrown.
    
                          
                          
                            ///
                          
                          
                            </summary>
                          
                          
                            ///
                          
                          
                            <param name="options">
                          
                          
                            The options being validated.
                          
                          
                            </param>
                          
                          
                            void
                          
                          
                             Validate(IDbContextOptions options);
}
                          
                        
                          
                            void
                          
                           IDbContextOptionsBuilderInfrastructure.AddOrUpdateExtension<TExtension>
                          
                            (TExtension extension)
        
                          
                          => _options = _options.WithExtension(extension);
                        

    在AddDbContext的最后,这几行代码,是将我们的DbContext注入到我们的IOC容器中去.

                          
                            if
                          
                           (serviceCollection.Any(d => d.ServiceType == 
                          
                            typeof
                          
                          (IDbContextFactorySource<TContextImplementation>
                          
                            )))
{
    
                          
                          
                            //
                          
                          
                             Override registration made by AddDbContextFactory
                          
                          
                            var
                          
                           serviceDescriptor = serviceCollection.FirstOrDefault(d => d.ServiceType == 
                          
                            typeof
                          
                          
                            (TContextImplementation));
    
                          
                          
                            if
                          
                           (serviceDescriptor != 
                          
                            null
                          
                          
                            )
    {
        serviceCollection.Remove(serviceDescriptor);
    }
}

serviceCollection.TryAdd(
                          
                          
                            new
                          
                           ServiceDescriptor(
                          
                            typeof
                          
                          (TContextService), 
                          
                            typeof
                          
                          
                            (TContextImplementation), contextLifetime));


                          
                          
                            if
                          
                           (
                          
                            typeof
                          
                          (TContextService) != 
                          
                            typeof
                          
                          
                            (TContextImplementation))
{
    serviceCollection.TryAdd(
        
                          
                          
                            new
                          
                          
                             ServiceDescriptor(
            
                          
                          
                            typeof
                          
                          
                            (TContextImplementation),
            p 
                          
                          => (TContextImplementation)p.GetService<TContextService>()!
                          
                            ,
            contextLifetime));
}
                          
                        

    至此,关于AddDbContext的源码讲解完毕,接下来进到DbContext构造函数的源码讲解,这里设计内容稍微多一些.

DBContext构造

    构造函数的代码是整体是没多少的,但是最重要的还是在于GetOrAdd的方法。所以这里我会只讲这个方法的内部 。

                          
                            public
                          
                          
                             DbContext(DbContextOptions options)
 {
     Check.NotNull(options, nameof(options));

     
                          
                          
                            if
                          
                           (!
                          
                            options.ContextType.IsAssignableFrom(GetType()))
     {
         
                          
                          
                            throw
                          
                          
                            new
                          
                          
                             InvalidOperationException(CoreStrings.NonGenericOptions(GetType().ShortDisplayName()));
     }

     _options 
                          
                          =
                          
                             options;

     
                          
                          
                            //
                          
                          
                             This service is not stored in _setInitializer as this may not be the service provider that will be used
     
                          
                          
                            //
                          
                          
                             as the internal service provider going forward, because at this time OnConfiguring has not yet been called.
     
                          
                          
                            //
                          
                          
                             Mostly that isn't a problem because set initialization is done by our internal services, but in the case
     
                          
                          
                            //
                          
                          
                             where some of those services are replaced, this could initialize set using non-replaced services.
     
                          
                          
                            //
                          
                          
                             In this rare case if this is a problem for the app, then the app can just not use this mechanism to create
     
                          
                          
                            //
                          
                          
                             DbSet instances, and this code becomes a no-op. However, if this set initializer is then saved and used later
     
                          
                          
                            //
                          
                          
                             for the Set method, then it makes the problem bigger because now an app is using the non-replaced services
     
                          
                          
                            //
                          
                          
                             even when it doesn't need to.
                          
                          
     ServiceProviderCache.Instance.GetOrAdd(options, providerRequired: 
                          
                            false
                          
                          
                            )
         .GetRequiredService
                          
                          <IDbSetInitializer>
                          
                            ()
         .InitializeSets(
                          
                          
                            this
                          
                          
                            );

     EntityFrameworkEventSource.Log.DbContextInitializing();
 }
                          
                        

    下面是ServiceProviderCache的全部源码,在GetOrAdd方法,先获取了CoreOptionsExtension,这个我们在AddDbContext的时候,已经添加过了,并且设置了ApplicationProvider,在往下走,判断InternalServiceProvider,这里我们没有设置,就会继续往下走,判断了一个ServiceProviderCachingEnabled 这个默认是true,然后下面获取CoreOptionsExtension的ApplicationServiceProvider,还记得我们在最初的时候AddDbContext的时候,创建DbContextOptionsBuilder的时候,我们UseApplicationServiceProvider方法,就是设置了一个公用的Provider,现在把他在设置为null,如果说这个Provider有啥作用,哈哈哈哈,我认为他就是创建Options的时候需要用,然后给一个有东西的不为空的CoreOptionsExtension,这个方法,实际上我觉得微软设置为internal最好了,这样可能会存在误解开发者,而InternalServiceProvider是很有用,可以和我们的web共用一个ioc容器,在本文的最后,我会将ef的ioc容器托管到web的.

    ServiceProviderCachingEnabled参数代表是否将GetOrAdd通过BuildServiceProvider创建的ServiceProvider缓存到_configuration中去,不缓存的话,每次都是一个新的Provider,对性能有影响,如果缓存,则第一次创建后面都是从那里面取.

    接下来就到了GetOrAdd最后,要调用BuildServiceProvider方法来创建一个ServiceProvider,下面的方法,我们着重看几个关键点一个是ApplyService,一个是new ServiceCollection(说明web的ioc和ef的ioc不是同一个),ReplaceService.

                          
                            public
                          
                          
                            class
                          
                          
                             ServiceProviderCache
{
    
                          
                          
                            private
                          
                          
                            readonly
                          
                           ConcurrentDictionary<IDbContextOptions, (IServiceProvider ServiceProvider, IDictionary<
                          
                            string
                          
                          , 
                          
                            string
                          
                          > DebugInfo)>
                          
                            
        _configurations 
                          
                          = 
                          
                            new
                          
                          
                            ();

    
                          
                          
                            ///
                          
                          
                            <summary>
                          
                          
                            ///
                          
                          
                                 This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    
                          
                          
                            ///
                          
                          
                                 the same compatibility standards as public APIs. It may be changed or removed without notice in
    
                          
                          
                            ///
                          
                          
                                 any release. You should only use it directly in your code with extreme caution and knowing that
    
                          
                          
                            ///
                          
                          
                                 doing so can result in application failures when updating to a new Entity Framework Core release.
    
                          
                          
                            ///
                          
                          
                            </summary>
                          
                          
                            public
                          
                          
                            static
                          
                           ServiceProviderCache Instance { 
                          
                            get
                          
                          ; } = 
                          
                            new
                          
                          
                            ();

    
                          
                          
                            ///
                          
                          
                            <summary>
                          
                          
                            ///
                          
                          
                                 This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    
                          
                          
                            ///
                          
                          
                                 the same compatibility standards as public APIs. It may be changed or removed without notice in
    
                          
                          
                            ///
                          
                          
                                 any release. You should only use it directly in your code with extreme caution and knowing that
    
                          
                          
                            ///
                          
                          
                                 doing so can result in application failures when updating to a new Entity Framework Core release.
    
                          
                          
                            ///
                          
                          
                            </summary>
                          
                          
                            public
                          
                          
                            virtual
                          
                           IServiceProvider GetOrAdd(IDbContextOptions options, 
                          
                            bool
                          
                          
                             providerRequired)
    {
        
                          
                          
                            var
                          
                           coreOptionsExtension = options.FindExtension<CoreOptionsExtension>
                          
                            ();
        
                          
                          
                            var
                          
                           internalServiceProvider = coreOptionsExtension?
                          
                            .InternalServiceProvider;
        
                          
                          
                            if
                          
                           (internalServiceProvider != 
                          
                            null
                          
                          
                            )
        {
            ValidateOptions(options);

            
                          
                          
                            var
                          
                           optionsInitializer = internalServiceProvider.GetService<ISingletonOptionsInitializer>
                          
                            ();
            
                          
                          
                            if
                          
                           (optionsInitializer == 
                          
                            null
                          
                          
                            )
            {
                
                          
                          
                            throw
                          
                          
                            new
                          
                          
                             InvalidOperationException(CoreStrings.NoEfServices);
            }

            
                          
                          
                            if
                          
                          
                             (providerRequired)
            {
                optionsInitializer.EnsureInitialized(internalServiceProvider, options);
            }

            
                          
                          
                            return
                          
                          
                             internalServiceProvider;
        }

        
                          
                          
                            if
                          
                           (coreOptionsExtension?.ServiceProviderCachingEnabled == 
                          
                            false
                          
                          
                            )
        {
            
                          
                          
                            return
                          
                          
                             BuildServiceProvider(options, (_configurations, options)).ServiceProvider;
        }

        
                          
                          
                            var
                          
                           cacheKey =
                          
                             options;
        
                          
                          
                            var
                          
                           extension = options.FindExtension<CoreOptionsExtension>
                          
                            ();
        
                          
                          
                            if
                          
                           (extension?.ApplicationServiceProvider != 
                          
                            null
                          
                          
                            )
        {
            cacheKey 
                          
                          = ((DbContextOptions)options).WithExtension(extension.WithApplicationServiceProvider(
                          
                            null
                          
                          
                            ));
        }

        
                          
                          
                            return
                          
                          
                             _configurations.GetOrAdd(
                cacheKey,
                
                          
                          
                            static
                          
                           (contextOptions, tuples) =>
                          
                             BuildServiceProvider(contextOptions, tuples), (_configurations, options))
            .ServiceProvider;

        
                          
                          
                            static
                          
                           (IServiceProvider ServiceProvider, IDictionary<
                          
                            string
                          
                          , 
                          
                            string
                          
                          >
                          
                             DebugInfo) BuildServiceProvider(
            IDbContextOptions _,
            (ConcurrentDictionary
                          
                          <IDbContextOptions, (IServiceProvider ServiceProvider, IDictionary<
                          
                            string
                          
                          , 
                          
                            string
                          
                          > DebugInfo)>
                          
                            ,
                IDbContextOptions) arguments)
        {
            
                          
                          
                            var
                          
                           (configurations, options) =
                          
                             arguments;

            ValidateOptions(options);

            
                          
                          
                            var
                          
                           debugInfo = 
                          
                            new
                          
                           Dictionary<
                          
                            string
                          
                          , 
                          
                            string
                          
                          >
                          
                            ();
            
                          
                          
                            foreach
                          
                           (
                          
                            var
                          
                           optionsExtension 
                          
                            in
                          
                          
                             options.Extensions)
            {
                optionsExtension.Info.PopulateDebugInfo(debugInfo);
            }

            debugInfo 
                          
                          = debugInfo.OrderBy(_ => debugInfo.Keys).ToDictionary(d => d.Key, v =>
                          
                             v.Value);

            
                          
                          
                            var
                          
                           services = 
                          
                            new
                          
                          
                             ServiceCollection();
            
                          
                          
                            var
                          
                           hasProvider =
                          
                             ApplyServices(options, services);

            
                          
                          
                            var
                          
                           replacedServices = options.FindExtension<CoreOptionsExtension>()?
                          
                            .ReplacedServices;
            
                          
                          
                            if
                          
                           (replacedServices != 
                          
                            null
                          
                          
                            )
            {
                
                          
                          
                            var
                          
                           updatedServices = 
                          
                            new
                          
                          
                             ServiceCollection();
                
                          
                          
                            foreach
                          
                           (
                          
                            var
                          
                           descriptor 
                          
                            in
                          
                          
                             services)
                {
                    
                          
                          
                            if
                          
                           (replacedServices.TryGetValue((descriptor.ServiceType, descriptor.ImplementationType), 
                          
                            out
                          
                          
                            var
                          
                          
                             replacementType))
                    {
                        ((IList
                          
                          <ServiceDescriptor>
                          
                            )updatedServices).Add(
                            
                          
                          
                            new
                          
                          
                             ServiceDescriptor(descriptor.ServiceType, replacementType, descriptor.Lifetime));
                    }
                    
                          
                          
                            else
                          
                          
                            if
                          
                           (replacedServices.TryGetValue((descriptor.ServiceType, 
                          
                            null
                          
                          ), 
                          
                            out
                          
                          
                             replacementType))
                    {
                        ((IList
                          
                          <ServiceDescriptor>
                          
                            )updatedServices).Add(
                            
                          
                          
                            new
                          
                          
                             ServiceDescriptor(descriptor.ServiceType, replacementType, descriptor.Lifetime));
                    }
                    
                          
                          
                            else
                          
                          
                            
                    {
                        ((IList
                          
                          <ServiceDescriptor>
                          
                            )updatedServices).Add(descriptor);
                    }
                }

                services 
                          
                          =
                          
                             updatedServices;
            }

            
                          
                          
                            var
                          
                           serviceProvider =
                          
                             services.BuildServiceProvider();

            
                          
                          
                            if
                          
                          
                             (hasProvider)
            {
                serviceProvider
                    .GetRequiredService
                          
                          <ISingletonOptionsInitializer>
                          
                            ()
                    .EnsureInitialized(serviceProvider, options);
            }

            
                          
                          
                            using
                          
                           (
                          
                            var
                          
                           scope =
                          
                             serviceProvider.CreateScope())
            {
                
                          
                          
                            var
                          
                           scopedProvider =
                          
                             scope.ServiceProvider;

                
                          
                          
                            //
                          
                          
                             If loggingDefinitions is null, then there is no provider yet
                          
                          
                            var
                          
                           loggingDefinitions = scopedProvider.GetService<LoggingDefinitions>
                          
                            ();
                
                          
                          
                            if
                          
                           (loggingDefinitions != 
                          
                            null
                          
                          
                            )
                {
                    
                          
                          
                            //
                          
                          
                             Because IDbContextOptions cannot yet be resolved from the internal provider
                          
                          
                            var
                          
                           logger = 
                          
                            new
                          
                           DiagnosticsLogger<DbLoggerCategory.Infrastructure>
                          
                            (
                        ScopedLoggerFactory.Create(scopedProvider, options),
                        scopedProvider.GetRequiredService
                          
                          <ILoggingOptions>
                          
                            (),
                        scopedProvider.GetRequiredService
                          
                          <DiagnosticSource>
                          
                            (),
                        loggingDefinitions,
                        
                          
                          
                            new
                          
                          
                             NullDbContextLogger());

                    
                          
                          
                            if
                          
                          
                             (configurations.IsEmpty)
                    {
                        logger.ServiceProviderCreated(serviceProvider);
                    }
                    
                          
                          
                            else
                          
                          
                            
                    {
                        logger.ServiceProviderDebugInfo(
                            debugInfo,
                            configurations.Values.Select(v 
                          
                          =>
                          
                             v.DebugInfo).ToList());

                        
                          
                          
                            if
                          
                           (configurations.Count >= 
                          
                            20
                          
                          
                            )
                        {
                            logger.ManyServiceProvidersCreatedWarning(
                                configurations.Values.Select(e 
                          
                          =>
                          
                             e.ServiceProvider).ToList());
                        }
                    }

                    
                          
                          
                            var
                          
                           applicationServiceProvider = options.FindExtension<CoreOptionsExtension>()?
                          
                            .ApplicationServiceProvider;
                    
                          
                          
                            if
                          
                           (applicationServiceProvider?.GetService<IRegisteredServices>() != 
                          
                            null
                          
                          
                            )
                    {
                        logger.RedundantAddServicesCallWarning(serviceProvider);
                    }
                }
            }

            
                          
                          
                            return
                          
                          
                             (serviceProvider, debugInfo);
        }
    }

    
                          
                          
                            private
                          
                          
                            static
                          
                          
                            void
                          
                          
                             ValidateOptions(IDbContextOptions options)
    {
        
                          
                          
                            foreach
                          
                           (
                          
                            var
                          
                           extension 
                          
                            in
                          
                          
                             options.Extensions)
        {
            extension.Validate(options);
        }
    }

    
                          
                          
                            private
                          
                          
                            static
                          
                          
                            bool
                          
                          
                             ApplyServices(IDbContextOptions options, ServiceCollection services)
    {
        
                          
                          
                            var
                          
                           coreServicesAdded = 
                          
                            false
                          
                          
                            ;

        
                          
                          
                            foreach
                          
                           (
                          
                            var
                          
                           extension 
                          
                            in
                          
                          
                             options.Extensions)
        {
            extension.ApplyServices(services);

            
                          
                          
                            if
                          
                          
                             (extension.Info.IsDatabaseProvider)
            {
                coreServicesAdded 
                          
                          = 
                          
                            true
                          
                          
                            ;
            }
        }

        
                          
                          
                            if
                          
                          
                             (coreServicesAdded)
        {
            
                          
                          
                            return
                          
                          
                            true
                          
                          
                            ;
        }

        
                          
                          
                            new
                          
                          
                             EntityFrameworkServicesBuilder(services).TryAddCoreServices();

        
                          
                          
                            return
                          
                          
                            false
                          
                          
                            ;
    }
}
                          
                        

     我们先看ApplyService,在这个方法我们看到,是传入了Options,ServiceCollection,然后循环遍历Options的Extensions,调用他的ApplyService方法,传入serviceCollection,下图,我们看到默认是有这么多的实现,根据你在对DBContextOptionsBuilder提供的方法的使用,会给Options的Extensions添加不同的Extension,最后调用各自的ApplyService,我们找一个看看具体在做什么事情。哈哈,不用猜,大家也知道,肯定是注入服务,通过options的Extensions附加一些其他关于EF的功能,并且将他们所需要的服务注入到传入的ServiceCollection里面,其他的都是一样,所以在我们没有托管ef的ioc到web的时候可以使用这种方式来实现,后面也会写一个这样的例子。最后调用一下TryAddCoreService方法,这个方法有许多EF需用到重要的服务的注入.

    而ReplaceService就是我们在调用DbContextOptionsBuilder的ReplaceService<>方法的时候里面保存的我们要替换的类型,以及实现,在这里重新注入到容器里,用上面的代码结合看,就是ApplyService先注入一遍,然后在替换一下,最后调用一下BuildServiceProvider方法生成一个ServiceProvider,在后面的代码就是一些日志相关的配置,此处就不过多讲解.

                          
                            public
                          
                          
                            virtual
                          
                          
                            void
                          
                          
                             ApplyServices(IServiceCollection services)
        
                          
                          => services.AddEntityFrameworkProxies();
                        

  。

      在上面的讲解中,我们有几个可以自定义的点就是一个是IDbContextOptionsExtension,这个我们可以在不托管ef的ioc到web的ioc的时候,我们可以实现一个这个接口,然后在代码添加到Extension就可以注入EF所需要用到的服务。接下来在下面段落,我会写一个简单的例子来注入我们要的服务。(不托管ioc到web的方式).

EFCore服务注入

    先上代码,代码没有多少,就是实现这个接口,定义一个Inject特性,用来标记从Web的IOC我们需要检索那些接口注入到EF的ioc中去,这样做有一个弊端就是Web的会注入一遍,Ef也会注入一遍,重复注入,在Program.cs里面我们先注入一个返回IServiceCollection的Func,这样在DBContext可以获取到这个 传到ServiceExtension里面,就可以拿到Web的IOC注入的服务.

                              builder.Services.AddScoped<IWebGetName, WebGetName>
                          
                            ();
    builder.Services.AddSingleton(() 
                          
                          => builder.Services);
                        
                          
                              [InjectAttribute]
  
                          
                          
                            public
                          
                          
                            interface
                          
                          
                             IWebGetName
  {
      
                          
                          
                            public
                          
                          
                            string
                          
                          
                             GetName();
  }
                          
                        
                           [AttributeUsage(AttributeTargets.Interface|
                          
                             AttributeTargets.Class)]
 
                          
                          
                            public
                          
                          
                            class
                          
                          
                             InjectAttribute:Attribute
 {
     
                          
                          
                            public
                          
                          
                             InjectAttribute()
     {
             
     }
 }
                          
                        

  。

                          
                            public
                          
                          
                            class
                          
                          
                             ServiceExtension : IDbContextOptionsExtension
{
    
                          
                          
                            public
                          
                           ServiceExtension(Func<IServiceCollection>
                          
                             func)
    {
        Func 
                          
                          =
                          
                             func;
    }
    
                          
                          
                            public
                          
                           DbContextOptionsExtensionInfo Info => 
                          
                            new
                          
                           ExtensionInfo(
                          
                            this
                          
                          
                            );

    
                          
                          
                            public
                          
                           Func<IServiceCollection> Func { 
                          
                            get
                          
                          
                            ; }

    
                          
                          
                            public
                          
                          
                            void
                          
                          
                             ApplyServices(IServiceCollection services)
    {
        
                          
                          
                            var
                          
                           ser=
                          
                            Func();
        
                          
                          
                            var
                          
                           type = ser.Where(s => s.ServiceType?.GetCustomAttribute<InjectAttribute>() != 
                          
                            null
                          
                           || s.ImplementationType?.GetCustomAttribute<InjectAttribute>() != 
                          
                            null
                          
                          
                            ).ToList();
        
                          
                          
                            foreach
                          
                           (
                          
                            var
                          
                           item 
                          
                            in
                          
                          
                             type)
        {
            services.TryAdd(
                          
                          
                            new
                          
                          
                             ServiceDescriptor(item.ServiceType, item.ImplementationType, item.Lifetime));
        }
        services.AddScoped
                          
                          <IDBGetName, DBGetName>
                          
                            ();
    }

    
                          
                          
                            public
                          
                          
                            void
                          
                          
                             Validate(IDbContextOptions options)
    {
    }
}
 
                          
                          
                            public
                          
                          
                            class
                          
                          
                             ExtensionInfo: DbContextOptionsExtensionInfo
 {
     
                          
                          
                            public
                          
                           ExtensionInfo(IDbContextOptionsExtension extension):
                          
                            base
                          
                          
                            (extension) 
     {
             
     }
     
                          
                          
                            public
                          
                          
                            override
                          
                          
                            bool
                          
                           IsDatabaseProvider => 
                          
                            false
                          
                          
                            ;

     
                          
                          
                            public
                          
                          
                            override
                          
                          
                            string
                          
                           LogFragment => 
                          
                            string
                          
                          
                            .Empty;

     
                          
                          
                            public
                          
                          
                            override
                          
                          
                            int
                          
                          
                             GetServiceProviderHashCode()
     {
         
                          
                          
                            return
                          
                          
                            0
                          
                          
                            ;
     }

     
                          
                          
                            public
                          
                          
                            override
                          
                          
                            void
                          
                           PopulateDebugInfo(IDictionary<
                          
                            string
                          
                          , 
                          
                            string
                          
                          >
                          
                             debugInfo)
     {
     }

     
                          
                          
                            public
                          
                          
                            override
                          
                          
                            bool
                          
                          
                             ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo other)
     {
         
                          
                          
                            return
                          
                          
                            true
                          
                          
                            ;
     }
 }
                          
                        

    接口定义好之后,服务也注入进去,接下来就是在DBContext里面添加这个扩展,因为optionsBuilder.Options只读,所以我们添加Extension就需要用AddOrUpdateExtension的方法来添加,因为Options在DbContextOptionsBuilder的内部字段是可以更改的。接下来扩展添加进去之后,我们运行程序,获取一个DBContext,然后就会走到这里添加我们的扩展,从而注入我们注入的IWebGetName,就可以在EF的IOC获取我们web注入服务.

                            builder.Services.AddDbContext<DecodeMicroMsgContext>((a, m) =>
                          
                             {

      ((IDbContextOptionsBuilderInfrastructure)m).AddOrUpdateExtension(
                          
                          
                            new
                          
                           ServiceExtension(a.GetService<Func<IServiceCollection>>
                          
                            ()));
      m.UseSqlite(
                          
                          
                            "
                          
                          
                            Data Source=C:\\Users\\Chenxd\\Desktop\\资料\\CrackMsg\\CrackDb\\CrackDb\\bin\\Debug\\net7.0-windows\\TOOLS\\output\\decode_MicroMsg.db;
                          
                          
                            "
                          
                          
                            );
  });
                          
                        

拦截查询

  Sql拦截

    针对SQL拦截,这里我会直接贴上我之前有一篇文章aop的代码,来作为讲解,其中有用到了DBInterceptor作为拦截器拦截DBCommand进行sql拦截,实现读写分离的方式,下面的代码是我自己实现了DBCommandInterceptor来实现的一个拦截器,在DBContext中将拦截器添加进去,在每次执行查询或者增加删除修改的时候,都会进入这个拦截器,从而实现自己想要的业务逻辑,我在此处是写了一个简单的读写分离,感兴趣的可以看看之前的文章 https://www.cnblogs.com/1996-Chinese-Chen/p/15776120.html 这个文章的代码地址已经失效,最后我会将本例程的所有代码放在百度网盘,其中包括这个AOP的代码,感兴趣的朋友可以下载看看.

                          
                            var
                          
                           list=
                          
                            new
                          
                           List<IInterceptor>
                          
                            ();
    list.Add(
                          
                          
                            new
                          
                          
                             DbContextInterceptor());
    optionsBuilder.AddInterceptors(list);
                          
                        
                          
                            public
                          
                          
                            class
                          
                          
                             DbContextInterceptor:DbCommandInterceptor
    {
        
                          
                          
                            private
                          
                          
                              DbConnection _connection;
        
                          
                          
                            private
                          
                          
                              DbCommand _command;
        
                          
                          
                            private
                          
                          
                             CommandSource _commandSource;
        
                          
                          
                            public
                          
                          
                             DbContextInterceptor()
        {

        }
        
                          
                          
                            public
                          
                          
                            override
                          
                          
                             DbCommand CommandCreated(CommandEndEventData eventData, DbCommand result)
        {
            
                          
                          
                            return
                          
                          
                             _command;
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                           InterceptionResult<DbCommand> CommandCreating(CommandCorrelatedEventData eventData, InterceptionResult<DbCommand>
                          
                             result)
        {
            _commandSource 
                          
                          =
                          
                             eventData.CommandSource;
            
                          
                          
                            if
                          
                           (eventData.CommandSource==
                          
                            CommandSource.LinqQuery)
            {
                _connection 
                          
                          = 
                          
                            new
                          
                          
                             MySqlConnection(eventData.Connection.ConnectionString);
                _command 
                          
                          = 
                          
                            new
                          
                          
                             MySqlCommand();
            }
            
                          
                          
                            return
                          
                           InterceptionResult<DbCommand>
                          
                            .SuppressWithResult(_command);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                          
                            void
                          
                          
                             CommandFailed(DbCommand command, CommandErrorEventData eventData)
        {
            
                          
                          
                            base
                          
                          
                            .CommandFailed(command, eventData);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                           Task CommandFailedAsync(DbCommand command, CommandErrorEventData eventData, CancellationToken cancellationToken = 
                          
                            default
                          
                          
                            )
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .CommandFailedAsync(command, eventData, cancellationToken);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                          
                             InterceptionResult DataReaderDisposing(DbCommand command, DataReaderDisposingEventData eventData, InterceptionResult result)
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .DataReaderDisposing(command, eventData, result);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                          
                            int
                          
                           NonQueryExecuted(DbCommand command, CommandExecutedEventData eventData, 
                          
                            int
                          
                          
                             result)
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .NonQueryExecuted(command, eventData, result);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                           ValueTask<
                          
                            int
                          
                          > NonQueryExecutedAsync(DbCommand command, CommandExecutedEventData eventData, 
                          
                            int
                          
                           result, CancellationToken cancellationToken = 
                          
                            default
                          
                          
                            )
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .NonQueryExecutedAsync(command, eventData, result, cancellationToken);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                           InterceptionResult<
                          
                            int
                          
                          > NonQueryExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<
                          
                            int
                          
                          >
                          
                             result)
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .NonQueryExecuting(command, eventData, result);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                           ValueTask<InterceptionResult<
                          
                            int
                          
                          >> NonQueryExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<
                          
                            int
                          
                          > result, CancellationToken cancellationToken = 
                          
                            default
                          
                          
                            )
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .NonQueryExecutingAsync(command, eventData, result, cancellationToken);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                          
                             DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEventData eventData, DbDataReader result)
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .ReaderExecuted(command, eventData, result);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                           ValueTask<DbDataReader> ReaderExecutedAsync(DbCommand command, CommandExecutedEventData eventData, DbDataReader result, CancellationToken cancellationToken = 
                          
                            default
                          
                          
                            )
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .ReaderExecutedAsync(command, eventData, result, cancellationToken);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                           InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader>
                          
                             result)
        {
            command.CommandText 
                          
                          = 
                          
                            ""
                          
                          
                            ;
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .ReaderExecuting(command, eventData, result);
        }
        
                          
                          
                            public
                          
                          
                            async
                          
                          
                            override
                          
                           ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result, CancellationToken cancellationToken = 
                          
                            default
                          
                          
                            )
        {
            InterceptionResult
                          
                          <DbDataReader>
                          
                             results;
            
                          
                          
                            if
                          
                           (_commandSource ==
                          
                             CommandSource.LinqQuery)
            {
                
                          
                          
                            var
                          
                           connect = 
                          
                            new
                          
                           MySqlConnection(
                          
                            "
                          
                          
                            data source=192.168.21.129;database=MasterSlave; userid=root;pwd=199645; charset=utf8;ConvertZeroDateTime=True;pooling=true; allowuservariables=true;
                          
                          
                            "
                          
                          
                            );
                connect.Open();
                _command 
                          
                          = 
                          
                            new
                          
                          
                             MySqlCommand(command.CommandText, connect);
                
                          
                          
                            var
                          
                           reader = 
                          
                            await
                          
                          
                             _command.ExecuteReaderAsync();
                results 
                          
                          = InterceptionResult<DbDataReader>
                          
                            .SuppressWithResult(reader);
            }
            
                          
                          
                            else
                          
                          
                            
            {
                results
                          
                          =
                          
                            await
                          
                          
                            base
                          
                          
                            .ReaderExecutingAsync(command, eventData, result, cancellationToken);
            }
            
                          
                          
                            return
                          
                          
                             results;
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                          
                            object
                          
                           ScalarExecuted(DbCommand command, CommandExecutedEventData eventData, 
                          
                            object
                          
                          
                             result)
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .ScalarExecuted(command, eventData, result);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                           ValueTask<
                          
                            object
                          
                          > ScalarExecutedAsync(DbCommand command, CommandExecutedEventData eventData, 
                          
                            object
                          
                           result, CancellationToken cancellationToken = 
                          
                            default
                          
                          
                            )
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .ScalarExecutedAsync(command, eventData, result, cancellationToken);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                           InterceptionResult<
                          
                            object
                          
                          > ScalarExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<
                          
                            object
                          
                          >
                          
                             result)
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .ScalarExecuting(command, eventData, result);
        }
        
                          
                          
                            public
                          
                          
                            override
                          
                           ValueTask<InterceptionResult<
                          
                            object
                          
                          >> ScalarExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<
                          
                            object
                          
                          > result, CancellationToken cancellationToken = 
                          
                            default
                          
                          
                            )
        {
            
                          
                          
                            return
                          
                          
                            base
                          
                          
                            .ScalarExecutingAsync(command, eventData, result, cancellationToken);
        }
    }
                          
                        

  表达式拦截

    上面我们讲了SQL拦截,接下来我们讲一下表达式拦截,我们都知道,EF的核心在于表达式树,可以说表达式树构造了整个EF的核心,关于表达式树,我在我的第一篇博客就写了很多关于表达式树的案例, https://www.cnblogs.com/1996-Chinese-Chen/p/14987967.html ,感兴趣的朋友可以看看,所以此处表达式树我不会做讲解,只有如何实现自定义的表达式树拦截, 。

    重要的有三个我们需要实现的接口,一个是IQueryable,IQueryCompiler,还有一个IAsyncQueryProvider,通过实现这三个接口,外加IDatabase,IQueryContextFactory需要用到的两个接口,实际上只是表达式拦截,只需要实现一个IQueryCompiler也可以实现,我i自己是实现了这三个,最主要的还是在IQueryCompiler,接下来看看具体的实现代码.

    IQueryCompiler

                          
                            public
                          
                          
                            class
                          
                          
                             TestQueryCompiler : IQueryCompiler
    {
        
                          
                          
                            public
                          
                          
                             TestQueryCompiler(IDatabase database, IQueryContextFactory queryContextFactory)
        {
            Database 
                          
                          =
                          
                             database;
            
                          
                          
                            var
                          
                           a =
                          
                             Database.GetType();
            QueryContextFactory 
                          
                          =
                          
                             queryContextFactory;
        }

        
                          
                          
                            public
                          
                           IDatabase Database { 
                          
                            get
                          
                          
                            ; }
        
                          
                          
                            public
                          
                           IQueryContextFactory QueryContextFactory { 
                          
                            get
                          
                          
                            ; }

        
                          
                          
                            public
                          
                           Func<QueryContext, TResult> CreateCompiledAsyncQuery<TResult>
                          
                            (Expression query)
        {
            
                          
                          
                            var
                          
                           queryFunc = Database.CompileQuery<TResult>(query, 
                          
                            true
                          
                          
                            );
            
                          
                          
                            return
                          
                          
                             queryFunc;
        }

        
                          
                          
                            public
                          
                           Func<QueryContext, TResult> CreateCompiledQuery<TResult>
                          
                            (Expression query)
        {
            
                          
                          
                            var
                          
                           queryFunc = Database.CompileQuery<TResult>(query, 
                          
                            false
                          
                          
                            );
            
                          
                          
                            return
                          
                          
                             queryFunc;
        }

        
                          
                          
                            public
                          
                           TResult Execute<TResult>
                          
                            (Expression query)
        {
            
                          
                          
                            var
                          
                           queryFunc = Database.CompileQuery<TResult>(query, 
                          
                            false
                          
                          
                            );
            
                          
                          
                            var
                          
                           res =
                          
                             queryFunc(QueryContextFactory.Create());
            
                          
                          
                            return
                          
                          
                             res;
        }

        
                          
                          
                            public
                          
                           TResult ExecuteAsync<TResult>
                          
                            (Expression query, CancellationToken cancellationToken)
        {
            
                          
                          
                            var
                          
                           queryFunc = Database.CompileQuery<TResult>(query, 
                          
                            true
                          
                          
                            );
            
                          
                          
                            var
                          
                           res =
                          
                             queryFunc(QueryContextFactory.Create());
            
                          
                          
                            return
                          
                          
                             res;
        }
    }
                          
                        

    IAsyncQueryProvider

                          
                            public
                          
                          
                            class
                          
                          
                             TestQueryProvider : IAsyncQueryProvider
 {
     
                          
                          
                            public
                          
                          
                             TestQueryProvider(IDBGetName ta, IQueryCompiler query,IWebGetName webGetName)
     {
         Ta 
                          
                          =
                          
                             ta;
         Query 
                          
                          =
                          
                             query;
         WebGetName 
                          
                          =
                          
                             webGetName;
     }

     
                          
                          
                            public
                          
                           IDBGetName Ta { 
                          
                            get
                          
                          
                            ; }
     
                          
                          
                            public
                          
                           IQueryCompiler Query { 
                          
                            get
                          
                          
                            ; }
     
                          
                          
                            public
                          
                           IWebGetName WebGetName { 
                          
                            get
                          
                          
                            ; }

     
                          
                          
                            public
                          
                          
                             IQueryable CreateQuery(Expression expression)
     {
         
                          
                          
                            return
                          
                          
                            new
                          
                           Queryable<
                          
                            object
                          
                          >(
                          
                            this
                          
                          
                            , expression);
     }

     
                          
                          
                            public
                          
                           IQueryable<TElement> CreateQuery<TElement>
                          
                            (Expression expression)
     {
         
                          
                          
                            return
                          
                          
                            new
                          
                           Queryable<TElement>(
                          
                            this
                          
                          
                            , expression);
     }

     
                          
                          
                            public
                          
                          
                            object
                          
                          ?
                          
                             Execute(Expression expression)
     {
         
                          
                          
                            return
                          
                           Query.Execute<
                          
                            object
                          
                          >
                          
                            (expression);
     }

     
                          
                          
                            public
                          
                           TResult Execute<TResult>
                          
                            (Expression expression)
     {
         
                          
                          
                            return
                          
                           Query.Execute<TResult>
                          
                            (expression);
     }

     
                          
                          
                            public
                          
                           TResult ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken = 
                          
                            default
                          
                          
                            )
     {
         
                          
                          
                            return
                          
                           Query.ExecuteAsync<TResult>
                          
                            (expression, cancellationToken);
     }
 }
                          
                        

    IQueryable

                          
                            public
                          
                          
                            class
                          
                           Queryable<T> : IQueryable<T>
                          
                            
 {
     
                          
                          
                            public
                          
                          
                             Queryable(IAsyncQueryProvider queryProvider, Expression expression)
     {
         QueryProvider 
                          
                          =
                          
                             queryProvider;
         Expression 
                          
                          =
                          
                             expression;
     }
     
                          
                          
                            public
                          
                           Type ElementType => 
                          
                            typeof
                          
                          
                            (T);

     
                          
                          
                            public
                          
                           IAsyncQueryProvider QueryProvider { 
                          
                            get
                          
                          
                            ; }
     
                          
                          
                            public
                          
                           Expression Expression { 
                          
                            get
                          
                          
                            ; }

     
                          
                          
                            public
                          
                           IQueryProvider Provider =>
                          
                             QueryProvider;

     
                          
                          
                            public
                          
                          
                             IEnumerator GetEnumerator()
     {
         
                          
                          
                            return
                          
                           Provider.Execute<IEnumerable>
                          
                            (Expression).GetEnumerator();
     }

     IEnumerator
                          
                          <T> IEnumerable<T>
                          
                            .GetEnumerator()
     {
         
                          
                          
                            return
                          
                           Provider.Execute<IEnumerable<T>>
                          
                            (Expression).GetEnumerator();
     }
 }
                          
                        

    在实现了那三个接口之后,我们就需要将我们的服务使用DBContextOptionsBuilder的ReplaceService替换掉,这样,在执行查询的时候就会走我们创建的TestQueryProvider,然后我们在这个类里调用关于Queryable和TestQueryCompiler来执行查询,如果又需要修改,也可以修改Expression从而达到拦截修改。我们最终是需要借助IDataBase的CompileQuery方法来实现构建查询的委托,从而实现查询,在底层还有Visitor遍历表达式树,当然了,此处我只展示一个拦截表达式树,后续的源码讲解会看到,欢迎大家关注.

    如果是使用了EF的IOC托管到了Web的IOC,只需要正常注入服务就行,生命周期是Scope, 。

                           #未接管
                          
optionsBuilder.ReplaceService<IAsyncQueryProvider,TestQueryProvider > (); optionsBuilder.ReplaceService <IQueryCompiler,TestQueryCompiler>();
#接管IOC

   builder.Services.AddScoped<IAsyncQueryProvider, TestQueryProvider>();    builder.Services.AddScoped<IQueryCompiler, TestQueryCompiler>(s =>    {    var database = s.GetService<IDatabase>();    var factory = s.GetService<IQueryContextFactory>();    return new TestQueryCompiler(database, factory);    }),

  。

  。

 缓存查询方法

    在上面的代码中,我们可以看到我们调用了一个ComileQuery方法,构建了一个委托,实际上,我们在业务编码中,也可以使用缓存查询,来提升业务系统的性能,虽然我们不能使用IDataBase的这个发给发,但是EF提供了一个静态类,里面的ComileQuery方法支持构建查询的委托, 。

     看下面代码,我们可以调用这个方法缓存一个查询的方法,后面就不会再去调用很多的类,很多的方法来实现我们的查询,可以缓存起来,来提升我们的查询性能,同时这个ComileQuery方法最终也会调用到我们上面自定义的TestQueryCompiler的ComileQuery方法去,并且同步对同步,异步对异步. 。

                          
                            public
                          
                          
                            class
                          
                          
                             WeatherForecastController : ControllerBase
  {
      
                          
                          
                            private
                          
                          
                            static
                          
                          
                            readonly
                          
                          
                            string
                          
                          [] Summaries = 
                          
                            new
                          
                          
                            []
      {
      
                          
                          
                            "
                          
                          
                            Freezing
                          
                          
                            "
                          
                          , 
                          
                            "
                          
                          
                            Bracing
                          
                          
                            "
                          
                          , 
                          
                            "
                          
                          
                            Chilly
                          
                          
                            "
                          
                          , 
                          
                            "
                          
                          
                            Cool
                          
                          
                            "
                          
                          , 
                          
                            "
                          
                          
                            Mild
                          
                          
                            "
                          
                          , 
                          
                            "
                          
                          
                            Warm
                          
                          
                            "
                          
                          , 
                          
                            "
                          
                          
                            Balmy
                          
                          
                            "
                          
                          , 
                          
                            "
                          
                          
                            Hot
                          
                          
                            "
                          
                          , 
                          
                            "
                          
                          
                            Sweltering
                          
                          
                            "
                          
                          , 
                          
                            "
                          
                          
                            Scorching
                          
                          
                            "
                          
                          
                            
  };
      
                          
                          
                            private
                          
                           Func<DecodeMicroMsgContext, IQueryable<Contact>>
                          
                             Func;
      
                          
                          
                            private
                          
                          
                            readonly
                          
                           ILogger<WeatherForecastController>
                          
                             _logger;
      
                          
                          
                            private
                          
                          
                            readonly
                          
                          
                             IWebGetName webGetName;

      
                          
                          
                            public
                          
                           WeatherForecastController(ILogger<WeatherForecastController>
                          
                             logger,IWebGetName webGetName, DecodeMicroMsgContext dbContext)
      {
          _logger 
                          
                          =
                          
                             logger;
          
                          
                          
                            this
                          
                          .webGetName =
                          
                             webGetName;
          DbContext 
                          
                          =
                          
                             dbContext;
      }

      
                          
                          
                            public
                          
                           DecodeMicroMsgContext DbContext { 
                          
                            get
                          
                          
                            ; }

      [HttpGet(Name 
                          
                          = 
                          
                            "
                          
                          
                            GetWeatherForecast
                          
                          
                            "
                          
                          
                            )]
      
                          
                          
                            public
                          
                           List<Contact>
                          
                             Get()
      {
          Func 
                          
                          = EF.CompileQuery<DecodeMicroMsgContext, IQueryable<Contact>>(s => s.Contacts.Take(
                          
                            10
                          
                          
                            ));
          
                          
                          
                            return
                          
                           DbContext.Contacts.Take(
                          
                            10
                          
                          
                            ).ToList();
      }
                          
                        

EF的IOC托管到WEB的IOC

    在上面讲源码的时候,我们提到了一个方法,叫UseInternalServiceProvider,我们需要借助这个方法来把EF的ioc托管到web,同样是DBContextOptionsBuilder的方法,将web的ServiceProvider获取到并且调用这个方法,同时,我们还需要在Program.cs调用一个方法  builder.Services.AddEntityFrameworkSqlite();如果是其他数据库也是一样的道理,需要调用这样的方法,可以看第三方提供的库源码,或者文档,这里我是SQLITE数据库,就调用这个方法,这个方法是将SqlLite的一些服务注入到容器里,并且将我们的web容器传入到EF里面去,这样EF注入的服务是和Web注入的服务是在一起的,然后在调用UseInternalServiceProvider指定ServiceProvider就可以实现EF和WEB共用一个IOC.

    下面是Program的Main方法的所有代码.

                          
                            public
                          
                          
                            static
                          
                          
                            void
                          
                           Main(
                          
                            string
                          
                          
                            [] args)
 {
     
                          
                          
                            var
                          
                           builder =
                          
                             WebApplication.CreateBuilder(args);
     builder.Services.AddScoped
                          
                          <IWebGetName,WebGetName>
                          
                            ();
     builder.Services.AddScoped
                          
                          <IAsyncQueryProvider, TestQueryProvider>
                          
                            ();
     builder.Services.AddScoped
                          
                          <IQueryCompiler, TestQueryCompiler>(s =>
                          
                            
     {
         
                          
                          
                            var
                          
                           database = s.GetService<IDatabase>
                          
                            ();
         
                          
                          
                            var
                          
                           factory = s.GetService<IQueryContextFactory>
                          
                            ();
         
                          
                          
                            return
                          
                          
                            new
                          
                          
                             TestQueryCompiler(database, factory);
     });
     builder.Services.AddScoped
                          
                          <IDBGetName, DBGetName>
                          
                            ();
     builder.Services.AddEntityFrameworkSqlite();
     builder.Services.AddDbContext
                          
                          <DecodeMicroMsgContext>((a, m) =>
                          
                             {
         m.UseSqlite(
                          
                          
                            "
                          
                          
                            Data Source=C:\\Users\\Chenxd\\Desktop\\资料\\CrackMsg\\CrackDb\\CrackDb\\bin\\Debug\\net7.0-windows\\TOOLS\\output\\decode_MicroMsg.db;
                          
                          
                            "
                          
                          
                            );
     });
     builder.Services.AddControllers();
     
                          
                          
                            //
                          
                          
                             Learn more about configuring Swagger/OpenAPI at 
                          
                          
                            https://aka.ms/aspnetcore/swashbuckle
                          
                          
                                 builder.Services.AddEndpointsApiExplorer();
     builder.Services.AddSwaggerGen();
     builder.Services.AddSingleton(() 
                          
                          =>
                          
                             builder.Services);
     
                          
                          
                            var
                          
                           app =
                          
                             builder.Build();

     
                          
                          
                            //
                          
                          
                             Configure the HTTP request pipeline.
                          
                          
                            if
                          
                          
                             (app.Environment.IsDevelopment())
     {
         app.UseSwagger();
         app.UseSwaggerUI();
     }

     app.UseAuthorization();


     app.MapControllers();

     app.Run();
 }
                          
                        

  。

                          
                            public
                          
                          
                            static
                          
                           IServiceCollection AddEntityFrameworkSqlite(
                          
                            this
                          
                          
                             IServiceCollection serviceCollection)
    {
        
                          
                          
                            var
                          
                           builder = 
                          
                            new
                          
                          
                             EntityFrameworkRelationalServicesBuilder(serviceCollection)
            .TryAdd
                          
                          <LoggingDefinitions, SqliteLoggingDefinitions>
                          
                            ()
            .TryAdd
                          
                          <IDatabaseProvider, DatabaseProvider<SqliteOptionsExtension>>
                          
                            ()
            .TryAdd
                          
                          <IRelationalTypeMappingSource, SqliteTypeMappingSource>
                          
                            ()
            .TryAdd
                          
                          <ISqlGenerationHelper, SqliteSqlGenerationHelper>
                          
                            ()
            .TryAdd
                          
                          <IRelationalAnnotationProvider, SqliteAnnotationProvider>
                          
                            ()
            .TryAdd
                          
                          <IModelValidator, SqliteModelValidator>
                          
                            ()
            .TryAdd
                          
                          <IProviderConventionSetBuilder, SqliteConventionSetBuilder>
                          
                            ()
            .TryAdd
                          
                          <IModificationCommandBatchFactory, SqliteModificationCommandBatchFactory>
                          
                            ()
            .TryAdd
                          
                          <IRelationalConnection>(p => p.GetRequiredService<ISqliteRelationalConnection>
                          
                            ())
            .TryAdd
                          
                          <IMigrationsSqlGenerator, SqliteMigrationsSqlGenerator>
                          
                            ()
            .TryAdd
                          
                          <IRelationalDatabaseCreator, SqliteDatabaseCreator>
                          
                            ()
            .TryAdd
                          
                          <IHistoryRepository, SqliteHistoryRepository>
                          
                            ()
            .TryAdd
                          
                          <IRelationalQueryStringFactory, SqliteQueryStringFactory>
                          
                            ()
            .TryAdd
                          
                          <IMethodCallTranslatorProvider, SqliteMethodCallTranslatorProvider>
                          
                            ()
            .TryAdd
                          
                          <IAggregateMethodCallTranslatorProvider, SqliteAggregateMethodCallTranslatorProvider>
                          
                            ()
            .TryAdd
                          
                          <IMemberTranslatorProvider, SqliteMemberTranslatorProvider>
                          
                            ()
            .TryAdd
                          
                          <IQuerySqlGeneratorFactory, SqliteQuerySqlGeneratorFactory>
                          
                            ()
            .TryAdd
                          
                          <IQueryableMethodTranslatingExpressionVisitorFactory, SqliteQueryableMethodTranslatingExpressionVisitorFactory>
                          
                            ()
            .TryAdd
                          
                          <IRelationalSqlTranslatingExpressionVisitorFactory, SqliteSqlTranslatingExpressionVisitorFactory>
                          
                            ()
            .TryAdd
                          
                          <IQueryTranslationPostprocessorFactory, SqliteQueryTranslationPostprocessorFactory>
                          
                            ()
            .TryAdd
                          
                          <IUpdateSqlGenerator>
                          
                            (
                sp 
                          
                          =>
                          
                            
                {
                    
                          
                          
                            //
                          
                          
                             Support for the RETURNING clause on INSERT/UPDATE/DELETE was added in Sqlite 3.35.
                    
                          
                          
                            //
                          
                          
                             Detect which version we're using, and fall back to the older INSERT/UPDATE+SELECT behavior on legacy versions.
                          
                          
                            var
                          
                           dependencies = sp.GetRequiredService<UpdateSqlGeneratorDependencies>
                          
                            ();

                    
                          
                          
                            return
                          
                          
                            new
                          
                           Version(
                          
                            new
                          
                           SqliteConnection().ServerVersion) < 
                          
                            new
                          
                           Version(
                          
                            3
                          
                          , 
                          
                            35
                          
                          
                            )
                        
                          
                          ? 
                          
                            new
                          
                          
                             SqliteLegacyUpdateSqlGenerator(dependencies)
                        : 
                          
                          
                            new
                          
                          
                             SqliteUpdateSqlGenerator(dependencies);
                })
            .TryAdd
                          
                          <ISqlExpressionFactory, SqliteSqlExpressionFactory>
                          
                            ()
            .TryAddProviderSpecificServices(
                b 
                          
                          => b.TryAddScoped<ISqliteRelationalConnection, SqliteRelationalConnection>
                          
                            ());

        builder.TryAddCoreServices();

        
                          
                          
                            return
                          
                          
                             serviceCollection;
    }
                          
                        

  。

                          
                            using
                          
                          
                             EfDemo.Models;

                          
                          
                            using
                          
                          
                             Microsoft.EntityFrameworkCore.Infrastructure;

                          
                          
                            using
                          
                          
                             Microsoft.EntityFrameworkCore.Query.Internal;

                          
                          
                            using
                          
                          
                             Microsoft.EntityFrameworkCore.Query;

                          
                          
                            using
                          
                          
                             Microsoft.EntityFrameworkCore;

                          
                          
                            using
                          
                          
                             EfDemo.QueryableExtension;

                          
                          
                            using
                          
                          
                             EfDemo.DBExtension;

                          
                          
                            using
                          
                          
                             Microsoft.EntityFrameworkCore.Diagnostics;


                          
                          
                            namespace
                          
                          
                             EfDemo.DB
{

    
                          
                          
                            public
                          
                          
                            partial
                          
                          
                            class
                          
                          
                             DecodeMicroMsgContext : DbContext
    {
        
                          
                          
                            public
                          
                           DecodeMicroMsgContext(Func<IServiceCollection>
                          
                             func, IServiceProvider serviceProvider)
        {
            Func 
                          
                          =
                          
                             func;
            ServiceProvider 
                          
                          =
                          
                             serviceProvider;
        }

        
                          
                          
                            public
                          
                           DecodeMicroMsgContext(DbContextOptions<DecodeMicroMsgContext> options, Func<IServiceCollection>
                          
                             func,IServiceProvider serviceProvider)
            : 
                          
                          
                            base
                          
                          
                            (options)
        {

            Func 
                          
                          =
                          
                             func;
            ServiceProvider 
                          
                          =
                          
                             serviceProvider;
        }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<AppInfo> AppInfos { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<BizInfo> BizInfos { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<BizName2Id> BizName2Ids { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<BizProfileInfo> BizProfileInfos { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<BizProfileV2> BizProfileV2s { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<BizSessionNewFeed> BizSessionNewFeeds { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<ChatInfo> ChatInfos { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<ChatLiveInfo> ChatLiveInfos { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<ChatRoom> ChatRooms { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<ChatRoomInfo> ChatRoomInfos { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<ChatroomTool> ChatroomTools { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<Contact> Contacts { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<ContactHeadImgUrl> ContactHeadImgUrls { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<ContactLabel> ContactLabels { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<DelayDownLoad> DelayDownLoads { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<FtschatroomTran> FtschatroomTrans { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<FtscontactTran> FtscontactTrans { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<MainConfig> MainConfigs { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<OpLog> OpLogs { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<PatInfo> PatInfos { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<RevokeMsgStorage> RevokeMsgStorages { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<Session> Sessions { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<TicketInfo> TicketInfos { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }

        
                          
                          
                            public
                          
                          
                            virtual
                          
                           DbSet<TopStoryReddotInfo> TopStoryReddotInfos { 
                          
                            get
                          
                          ; 
                          
                            set
                          
                          
                            ; }
        
                          
                          
                            public
                          
                           IServiceProvider ServiceProvider { 
                          
                            get
                          
                          
                            ; }
        
                          
                          
                            public
                          
                           IServiceCollection ServiceDescriptors { 
                          
                            get
                          
                          
                            ; }
        
                          
                          
                            public
                          
                           Func<IServiceCollection> Func { 
                          
                            get
                          
                          
                            ; }

        
                          
                          
                            protected
                          
                          
                            override
                          
                          
                            void
                          
                          
                             OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseInternalServiceProvider(ServiceProvider);
           
                          
                          
                            //
                          
                          
                             optionsBuilder.ReplaceService<IAsyncQueryProvider, TestQueryProvider>();
           
                          
                          
                            //
                          
                          
                             optionsBuilder.ReplaceService<IQueryCompiler, TestQueryCompiler>();
            
                          
                          
                            //
                          
                          
                             ((IDbContextOptionsBuilderInfrastructure)s).AddOrUpdateExtension(new Extension());
            
                          
                          
                            //
                          
                          
                            var interceptor = new List<IInterceptor>();
            
                          
                          
                            //
                          
                          
                            optionsBuilder.AddInterceptors();
                          
                          
            ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(
                          
                            new
                          
                          
                             ServiceExtension(Func));
            
                          
                          
                            base
                          
                          
                            .OnConfiguring(optionsBuilder);
        }

        
                          
                          
                            protected
                          
                          
                            override
                          
                          
                            void
                          
                          
                             OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity
                          
                          <AppInfo>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.InfoKey);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            AppInfo
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.Description4EnUs).HasColumnName(
                          
                            "
                          
                          
                            Description4EnUS
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Description4ZhTw).HasColumnName(
                          
                            "
                          
                          
                            Description4ZhTW
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Name4EnUs).HasColumnName(
                          
                            "
                          
                          
                            Name4EnUS
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Name4ZhTw).HasColumnName(
                          
                            "
                          
                          
                            Name4ZhTW
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Version).HasColumnType(
                          
                            "
                          
                          
                            INT
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <BizInfo>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.UserName);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            BizInfo
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.AcceptType).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.BrandFlag).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.BrandIconUrl).HasColumnName(
                          
                            "
                          
                          
                            BrandIconURL
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved1).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved3).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved5).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved7).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Type).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.UpdateTime).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <BizName2Id>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.UsrName);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            BizName2ID
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <BizProfileInfo>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.TableIndex);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            BizProfileInfo
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.TableIndex, 
                          
                            "
                          
                          
                            versionIdx
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          =>
                          
                             e.TableIndex)
                    .ValueGeneratedNever()
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            tableIndex
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.TableDesc).HasColumnName(
                          
                            "
                          
                          
                            tableDesc
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          =>
                          
                             e.TableVersion)
                    .HasColumnType(
                          
                          
                            "
                          
                          
                            INTERGER
                          
                          
                            "
                          
                          
                            )
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            tableVersion
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <BizProfileV2>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.TalkerId);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            BizProfileV2
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.TimeStamp, 
                          
                            "
                          
                          
                            BizProfileV2TimeIdx
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          =>
                          
                             e.TalkerId).ValueGeneratedNever();
            });

            modelBuilder.Entity
                          
                          <BizSessionNewFeed>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.TalkerId);

                entity.HasIndex(e 
                          
                          => e.CreateTime, 
                          
                            "
                          
                          
                            BizSessionNewFeedsCreateTimeIdx
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.UpdateTime, 
                          
                            "
                          
                          
                            BizSessionNewFeedsUpdateTimeIdx
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          =>
                          
                             e.TalkerId).ValueGeneratedNever();
            });

            modelBuilder.Entity
                          
                          <ChatInfo>(entity =>
                          
                            
            {
                entity
                    .HasNoKey()
                    .ToTable(
                          
                          
                            "
                          
                          
                            ChatInfo
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.Username, 
                          
                            "
                          
                          
                            ChatInfoUserNameIndex
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <ChatLiveInfo>(entity =>
                          
                            
            {
                entity
                    .HasNoKey()
                    .ToTable(
                          
                          
                            "
                          
                          
                            ChatLiveInfo
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => 
                          
                            new
                          
                           { e.RoomName, e.LiveId }, 
                          
                            "
                          
                          
                            IX_ChatLiveInfo_RoomName_LiveId
                          
                          
                            "
                          
                          
                            ).IsUnique();

                entity.HasIndex(e 
                          
                          => e.LiveId, 
                          
                            "
                          
                          
                            ChatLiveInfoLiveIdIdx
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.RoomName, 
                          
                            "
                          
                          
                            ChatLiveInfoRoomNamex
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <ChatRoom>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.ChatRoomName);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            ChatRoom
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          =>
                          
                             e.ChatRoomFlag)
                    .HasDefaultValueSql(
                          
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            )
                    .HasColumnType(
                          
                          
                            "
                          
                          
                            INT
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.IsShowName).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Owner).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved1).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved3).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved5).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved7).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <ChatRoomInfo>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.ChatRoomName);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            ChatRoomInfo
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.AnnouncementPublishTime).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.ChatRoomStatus).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.InfoVersion).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved1).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved3).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved5).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved7).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <ChatroomTool>(entity =>
                          
                            
            {
                entity
                    .HasNoKey()
                    .ToTable(
                          
                          
                            "
                          
                          
                            ChatroomTool
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.ChatroomUsername, 
                          
                            "
                          
                          
                            IX_ChatroomTool_ChatroomUsername
                          
                          
                            "
                          
                          
                            ).IsUnique();
            });

            modelBuilder.Entity
                          
                          <Contact>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.UserName);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            Contact
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.Reserved2, 
                          
                            "
                          
                          
                            Contact_Idx0
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.ChatRoomNotify).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.ChatRoomType).HasColumnType(
                          
                            "
                          
                          
                            INT
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.DelFlag).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.LabelIdlist).HasColumnName(
                          
                            "
                          
                          
                            LabelIDList
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Pyinitial).HasColumnName(
                          
                            "
                          
                          
                            PYInitial
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.RemarkPyinitial).HasColumnName(
                          
                            "
                          
                          
                            RemarkPYInitial
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved1).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved2).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved5).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved8).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved9).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Type).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.VerifyFlag).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <ContactHeadImgUrl>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.UsrName);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            ContactHeadImgUrl
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.Reverse0, 
                          
                            "
                          
                          
                            reverse0Index
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.UsrName).HasColumnName(
                          
                            "
                          
                          
                            usrName
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.BigHeadImgUrl).HasColumnName(
                          
                            "
                          
                          
                            bigHeadImgUrl
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.HeadImgMd5).HasColumnName(
                          
                            "
                          
                          
                            headImgMd5
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          =>
                          
                             e.Reverse0)
                    .HasColumnType(
                          
                          
                            "
                          
                          
                            INT
                          
                          
                            "
                          
                          
                            )
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            reverse0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reverse1).HasColumnName(
                          
                            "
                          
                          
                            reverse1
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.SmallHeadImgUrl).HasColumnName(
                          
                            "
                          
                          
                            smallHeadImgUrl
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <ContactLabel>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.LabelId);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            ContactLabel
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          =>
                          
                             e.LabelId).ValueGeneratedNever();
            });

            modelBuilder.Entity
                          
                          <DelayDownLoad>(entity =>
                          
                            
            {
                entity
                    .HasNoKey()
                    .ToTable(
                          
                          
                            "
                          
                          
                            DelayDownLoad
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.MessageServId, 
                          
                            "
                          
                          
                            IX_DelayDownLoad_MessageServId
                          
                          
                            "
                          
                          
                            ).IsUnique();
            });

            modelBuilder.Entity
                          
                          <FtschatroomTran>(entity =>
                          
                            
            {
                entity
                    .HasNoKey()
                    .ToTable(
                          
                          
                            "
                          
                          
                            FTSChatroomTrans
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.DisplayName).HasColumnName(
                          
                            "
                          
                          
                            displayName
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.GroupUsername).HasColumnName(
                          
                            "
                          
                          
                            groupUsername
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Nickname).HasColumnName(
                          
                            "
                          
                          
                            nickname
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Operation).HasColumnName(
                          
                            "
                          
                          
                            operation
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserve1).HasColumnName(
                          
                            "
                          
                          
                            reserve1
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserve2).HasColumnName(
                          
                            "
                          
                          
                            reserve2
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Username).HasColumnName(
                          
                            "
                          
                          
                            username
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <FtscontactTran>(entity =>
                          
                            
            {
                entity
                    .HasNoKey()
                    .ToTable(
                          
                          
                            "
                          
                          
                            FTSContactTrans
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.Reserve1).HasColumnName(
                          
                            "
                          
                          
                            reserve1
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserve2).HasColumnName(
                          
                            "
                          
                          
                            reserve2
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Username).HasColumnName(
                          
                            "
                          
                          
                            username
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <MainConfig>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.Key);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            MainConfig
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.Reserved0, 
                          
                            "
                          
                          
                            MainConfigReserved0Idx
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.Reserved1, 
                          
                            "
                          
                          
                            MainConfigReserved1Idx
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.Reserved0).HasColumnType(
                          
                            "
                          
                          
                            INT
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved1).HasColumnType(
                          
                            "
                          
                          
                            INT
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <OpLog>(entity =>
                          
                            
            {
                entity.ToTable(
                          
                          
                            "
                          
                          
                            OpLog
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          =>
                          
                             e.Id)
                    .ValueGeneratedNever()
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            ID
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.CmditemBuffer).HasColumnName(
                          
                            "
                          
                          
                            CMDItemBuffer
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <PatInfo>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.Username);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            PatInfo
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.Username).HasColumnName(
                          
                            "
                          
                          
                            username
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          =>
                          
                             e.Reserved1)
                    .HasDefaultValueSql(
                          
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            )
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            reserved1
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          =>
                          
                             e.Reserved2)
                    .HasDefaultValueSql(
                          
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            )
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            reserved2
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          =>
                          
                             e.Reserved3)
                    .HasDefaultValueSql(
                          
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            )
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            reserved3
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          =>
                          
                             e.Reserved4)
                    .HasDefaultValueSql(
                          
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            )
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            reserved4
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved5).HasColumnName(
                          
                            "
                          
                          
                            reserved5
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved6).HasColumnName(
                          
                            "
                          
                          
                            reserved6
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved7).HasColumnName(
                          
                            "
                          
                          
                            reserved7
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved8).HasColumnName(
                          
                            "
                          
                          
                            reserved8
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved9).HasColumnName(
                          
                            "
                          
                          
                            reserved9
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Suffix).HasColumnName(
                          
                            "
                          
                          
                            suffix
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <RevokeMsgStorage>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.CreateTime);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            RevokeMsgStorage
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.MsgSvrId, 
                          
                            "
                          
                          
                            MsgSvrId_Idx
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.RevokeSvrId, 
                          
                            "
                          
                          
                            RevokeSvrID_Idx
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          =>
                          
                             e.CreateTime).ValueGeneratedNever();
                entity.Property(e 
                          
                          =>
                          
                             e.MsgSvrId)
                    .HasColumnType(
                          
                          
                            "
                          
                          
                            INTERGER
                          
                          
                            "
                          
                          
                            )
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            MsgSvrID
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          =>
                          
                             e.RevokeSvrId)
                    .HasColumnType(
                          
                          
                            "
                          
                          
                            INTERGER
                          
                          
                            "
                          
                          
                            )
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            RevokeSvrID
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <Session>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.StrUsrName);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            Session
                          
                          
                            "
                          
                          
                            );

                entity.HasIndex(e 
                          
                          => e.NOrder, 
                          
                            "
                          
                          
                            nOrderIndex
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.StrUsrName).HasColumnName(
                          
                            "
                          
                          
                            strUsrName
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.BytesXml).HasColumnName(
                          
                            "
                          
                          
                            bytesXml
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.EditContent).HasColumnName(
                          
                            "
                          
                          
                            editContent
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.NIsSend).HasColumnName(
                          
                            "
                          
                          
                            nIsSend
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.NMsgLocalId).HasColumnName(
                          
                            "
                          
                          
                            nMsgLocalID
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.NMsgStatus).HasColumnName(
                          
                            "
                          
                          
                            nMsgStatus
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.NMsgType).HasColumnName(
                          
                            "
                          
                          
                            nMsgType
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          =>
                          
                             e.NOrder)
                    .HasDefaultValueSql(
                          
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            )
                    .HasColumnType(
                          
                          
                            "
                          
                          
                            INT
                          
                          
                            "
                          
                          
                            )
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            nOrder
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.NStatus).HasColumnName(
                          
                            "
                          
                          
                            nStatus
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.NTime).HasColumnName(
                          
                            "
                          
                          
                            nTime
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          =>
                          
                             e.NUnReadCount)
                    .HasDefaultValueSql(
                          
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            )
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            nUnReadCount
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          =>
                          
                             e.OthersAtMe)
                    .HasColumnType(
                          
                          
                            "
                          
                          
                            INT
                          
                          
                            "
                          
                          
                            )
                    .HasColumnName(
                          
                          
                            "
                          
                          
                            othersAtMe
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.ParentRef).HasColumnName(
                          
                            "
                          
                          
                            parentRef
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved0).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved2).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved4).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.StrContent).HasColumnName(
                          
                            "
                          
                          
                            strContent
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.StrNickName).HasColumnName(
                          
                            "
                          
                          
                            strNickName
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <TicketInfo>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.UserName);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            TicketInfo
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.Reserved1).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
                entity.Property(e 
                          
                          => e.Reserved3).HasDefaultValueSql(
                          
                            "
                          
                          
                            0
                          
                          
                            "
                          
                          
                            );
            });

            modelBuilder.Entity
                          
                          <TopStoryReddotInfo>(entity =>
                          
                            
            {
                entity.HasKey(e 
                          
                          =>
                          
                             e.MsgId);

                entity.ToTable(
                          
                          
                            "
                          
                          
                            TopStoryReddotInfo
                          
                          
                            "
                          
                          
                            );

                entity.Property(e 
                          
                          => e.H5version).HasColumnName(
                          
                            "
                          
                          
                            H5Version
                          
                          
                            "
                          
                          
                            );
            });

            OnModelCreatingPartial(modelBuilder);
        }

        
                          
                          
                            partial
                          
                          
                            void
                          
                          
                             OnModelCreatingPartial(ModelBuilder modelBuilder);
    }
}
                          
                        

结尾

    在本文中,我们一共讲了AddDbContext做了什么,DBContext的构造函数又做了那些事情,在写了不托管EF的ioc到WEB的ioc的场景下如果注入服务到EF的ioc中,以及如何拦截增删改查的方式,提升查询性能的方式,以及最后的EF的ioc托管到WEB的ioc,本文作为源码讲解的第一章,觉得写的有点多,如果又看不懂的地方,或者代码下载下来没办法运行或者保存的地方可以随时联系我,QQ934550201.我们下次再见。数据库是我破解的我本地的微信数据的一部分,emmm作为了本次的例子,我希望大家能够合理看待我的这个数据库的数据,不要做一些不好的事情,谢谢大家.

    本次的代码例子地址 。

               链接:https://pan.baidu.com/s/1w6kFG5MCJYE0jzEBxjQTKw 。

               提取码:foin 。

    之前AOP的代码例子 。

    链接:https://pan.baidu.com/s/1AJe4-KhjIESbDtFNqM968Q     提取码:jp20 。

最后此篇关于【源码解读(一)】EFCORE源码解读之创建DBContext查询拦截的文章就讲到这里了,如果你想了解更多关于【源码解读(一)】EFCORE源码解读之创建DBContext查询拦截的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com