一. 配置相关

1. 数据库连接字符串的写法

(1).账号密码:Server=localhost;Database=EFDB01;User ID=sa;Password=123456;

(2).windows身份:Server=localhost;Database=EFDB01;Trusted_Connection=True;

2. 命令超时和默认关闭状态追踪

(1).命令超时: providerOptions => providerOptions.CommandTimeout(60),表示60秒超时。

(2).关闭查询状态追踪:UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking),表示关闭追踪;

(PS: 默认是 QueryTrackingBehavior.TrackAll 开启追踪)

详见下面案例:

  a. QueryTrackingBehavior.NoTracking: 对应的是Detached状态,即有游离状态。

  b. QueryTrackingBehavior.TrackAll: 对应的是Unchanged状态,即未发生改变的。

             {
var d1 = context1.T_UserInfor.First();
//关闭跟踪对应的是:Detached;开启跟踪对应的是:Unchanged
var state = context1.Entry(d1).State;
}

3. 日志记录

  最好在控制台中配置,能输出生成的SQL语句。

配置代码分享:

  public partial class EFDB01Context : DbContext
{
//public static readonly LoggerFactory MyLoggerFactory = new LoggerFactory(new[] { new ConsoleLoggerProvider((_, __) => true, true) });
public static readonly LoggerFactory MyLoggerFactory = new LoggerFactory(new[]
{
new ConsoleLoggerProvider((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information, true)
});
public EFDB01Context()
{ }
public virtual DbSet<T_RoleInfor> T_RoleInfor { get; set; }
public virtual DbSet<T_UserInfor> T_UserInfor { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=localhost;Database=EFDB01;User ID=sa;Password=123456;").UseLoggerFactory(MyLoggerFactory);
}
}

输出结果:

4. 连接弹性

详见官方文章:https://docs.microsoft.com/zh-cn/ef/core/miscellaneous/connection-resiliency

5. 线程安全问题

(1).说明

  EF Core不支持在同一DbContext实例上运行多个并行操作。这包括异步查询的并行执行以及从多个线程进行的任何显式并发使用。因此,应await立即异步调用, 或对并行DbContext执行的操作使用单独的实例。

  当EFCore检测到并行使用某个DbContext实例时, 触发InvalidOperationException异常;但是当并发访问未被检测时, 可能会导致未定义的行为、应用程序崩溃和数据损坏.

(2).情况一:在对同一 DbContext 启动任何其他操作之前, 忘记等待异步操作完成。

  使用异步方法, EF Core 可以启动以非阻止方式访问数据库的操作。 但是, 如果调用方不等待其中一种方法完成, 并继续在上DbContext执行其他操作,则的DbContext状态可能会损坏。

(3).情况二:Core MVC通过依赖关系注入在多个线程之间隐式共享 DbContext 实例

  默认AddDbContext情况下,注入的上下文是请求内单例的,所以每个请求都获得了单独的DbContext,请求与请求之间的DbContext是线程安全的;但是,在同一个请求中,任何并行显式执行多个线程的代码都应该DbContext确保不会同时访问实例,否则会出现上述“情况一”的状况。

(4). 案例说明:要避免下面案例的那种情况,公用同一个上下文,是没法保证线程安全的

代码分享:

             {
var optionsBuilder = new DbContextOptionsBuilder<EFDB01Context>();
optionsBuilder.UseSqlServer(configuration.GetConnectionString("EFStr"));
EFDB01Context context = new EFDB01Context(optionsBuilder.Options);
Task.Run(() =>
{
while (true)
{
var u1 = new T_UserInfor()
{
id = Guid.NewGuid().ToString("N"),
userName = "ypf2",
userSex = "男2",
userAge = ,
addTime = DateTime.Now
};
context.Set<T_UserInfor>().Add(u1);
int result = context.SaveChanges();
}
}); Task.Run(() =>
{
while (true)
{
var u1 = new T_UserInfor()
{
id = Guid.NewGuid().ToString("N"),
userName = "ypf2",
userSex = "男2",
userAge = ,
addTime = DateTime.Now
};
context.Set<T_UserInfor>().Add(u1);
int result = context.SaveChanges();
}
});
Task.Delay(TimeSpan.FromMinutes()).Wait();
}

6. 连接数和连接池问题

(1).查询数据库连接数语句:SELECT * FROM SYSPROCESSES WHERE DBID = DB_ID('数据库名')

(2).手动设置连接池的最大(小)数量: "Server=localhost;Database=Test;Trusted_Connection=True;Max Pool Size=100;Min Pool Size=5"

(3).连接池的运行原理

概念:连接到数据源可能需要很长时间。 为了最大程度地降低打开连接的成本,ADO.NET 使用一种称为连接池的优化技术,这会最大程度地降低重复打开和关闭连接的成本。

A. 当一个程序执行Connection.open()时候,ADO.Net就需要判断,此连接是否支持Connection Pool (Pooling 默认为True)

 ①:如果指定为False, ADO.Net就与数据库之间创建一个连接,然后返回给程序。

 ②:如果指定为 True,ADO.Net就会根据ConnectString创建一个Connection Pool,然后向Connection Pool中填充Connection。填充多少个Connection由Min Pool Size (默认为0)属性来决定。例如如果指定为5,则ADO.Net会一次与SQL数据库之间打开5个连接,然后将4个Connection,保存在 Connection Pool中,1个Connection返回给程序。

B. 当程序执行到Connection.close() 的时候。如果Pooling 为True,ADO.net 就把当前的Connection放到Connection Pool并且保持与数据库之间的连接。

同时还会判断Connection Lifetime(默认为0)属性,0代表无限大,如果Connection存在的时间超过了Connection LifeTime,ADO.net就会关闭的Connection同时断开与数据库的连接,而不是重新保存到Connection Pool中。

C. 当下一次Connection.Open() 执行的时候,ADO.Net就会判断新的ConnectionString与之前保存在Connection Pool中的Connection的connectionString是否一致。

D. ADO.Net需要判断当前的Connection Pool中是否有可以使用的Connection(没有被其他程序所占用),如果没有的话,ADO.Net就需要判断ConnectionString设 置的Max Pool Size (默认为100)

 ①. 如果Connection Pool中的所有Connection没有达到Max Pool Size,ADO.net则会再次连接数据库,创建一个连接,然后将Connection返回给程序。

 ②. 如果已经达到了 Max Pool Size,ADO.Net就不会再次创建任何新的连接,而是等待Connection Pool中被其他程序所占用的Connection释放,这个等待时间受SqlConnection.ConnectionTimeout(默认是15 秒)限制,也就是说如果时间超过了15秒,SqlConnection就会抛出超时错误。

E. 如果有可用的Connection,从Connection Pool 取出的Connection也不是直接就返回给程序,ADO.Net还需要检查ConnectionString的ConnectionReset属性 (默认为True)是否需要对Connection 做一次reset。

更详细的介绍请参考官方文档:https://docs.microsoft.com/zh-cn/dotnet/framework/data/adonet/sql-server-connection-pooling

7. 总结

(1).SaveChanges的时候数据库连接自动释放,所以不需要手动释放。

(2).调用using的方法可以,因为dispose里讲很多东西都滞空了,完全没问题;但在Core MVC中,EF上下文都是通过依赖注入,能控制生命周期,所以不再需要using。

(3).手动open然后手动close,连接数没有释放,因为连接池的概念,当然你可以手动配置连接池数目(强制删除连接池:ClearAllPools),只有当IIS关闭,连接才彻底释放。

二. 生命周期

1.源码分析 

public enum ServiceLifetime { Singleton = 0, Scoped = 1, Transient = 2 }

(1).Singleton :整个应用程序生命周期以内只创建一个实例。

(2).Scoped: 在同一个Scope内只初始化一个实例 ,可以理解为(每一个 request 级别只创建一个实例)

(3).Transient: 每一次 GetService 都会创建一个新的实例。

注:默认是Scoped,即单次请求内是单例的。

可以自行配置:

通过查源码可知,默认就是Scoped的。

  //
// 摘要:
// Extension methods for setting up Entity Framework related services in an Microsoft.Extensions.DependencyInjection.IServiceCollection.
public static class EntityFrameworkServiceCollectionExtensions
{
//
// 摘要:
// Registers the given context as a service in the Microsoft.Extensions.DependencyInjection.IServiceCollection.
// You use this method when using dependency injection in your application, such
// as with ASP.NET. For more information on setting up dependency injection, see
// http://go.microsoft.com/fwlink/?LinkId=526890.
//
// 参数:
// serviceCollection:
// The Microsoft.Extensions.DependencyInjection.IServiceCollection to add services
// to.
//
// optionsAction:
// An optional action to configure the Microsoft.EntityFrameworkCore.DbContextOptions
// for the context. This provides an alternative to performing configuration of
// the context by overriding the Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// method in your derived context.
// If an action is supplied here, the Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// method will still be run if it has been overridden on the derived context. Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// configuration will be applied in addition to configuration performed here.
// In order for the options to be passed into your context, you need to expose a
// constructor on your context that takes Microsoft.EntityFrameworkCore.DbContextOptions`1
// and passes it to the base constructor of Microsoft.EntityFrameworkCore.DbContext.
//
// contextLifetime:
// The lifetime with which to register the DbContext service in the container.
//
// optionsLifetime:
// The lifetime with which to register the DbContextOptions service in the container.
//
// 类型参数:
// TContext:
// The type of context to be registered.
//
// 返回结果:
// The same service collection so that multiple calls can be chained.
public static IServiceCollection AddDbContext<TContext>([NotNullAttribute] this IServiceCollection serviceCollection, [CanBeNullAttribute] Action<DbContextOptionsBuilder> optionsAction = null, ServiceLifetime contextLifetime = ServiceLifetime.Scoped, ServiceLifetime optionsLifetime = ServiceLifetime.Scoped) where TContext : DbContext;
//
// 摘要:
// Registers the given context as a service in the Microsoft.Extensions.DependencyInjection.IServiceCollection.
// You use this method when using dependency injection in your application, such
// as with ASP.NET. For more information on setting up dependency injection, see
// http://go.microsoft.com/fwlink/?LinkId=526890.
//
// 参数:
// serviceCollection:
// The Microsoft.Extensions.DependencyInjection.IServiceCollection to add services
// to.
//
// optionsAction:
// An optional action to configure the Microsoft.EntityFrameworkCore.DbContextOptions
// for the context. This provides an alternative to performing configuration of
// the context by overriding the Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// method in your derived context.
// If an action is supplied here, the Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// method will still be run if it has been overridden on the derived context. Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// configuration will be applied in addition to configuration performed here.
// In order for the options to be passed into your context, you need to expose a
// constructor on your context that takes Microsoft.EntityFrameworkCore.DbContextOptions`1
// and passes it to the base constructor of Microsoft.EntityFrameworkCore.DbContext.
//
// contextLifetime:
// The lifetime with which to register the DbContext service in the container.
//
// optionsLifetime:
// The lifetime with which to register the DbContextOptions service in the container.
//
// 类型参数:
// TContextService:
// The class or interface that will be used to resolve the context from the container.
//
// TContextImplementation:
// The concrete implementation type to create.
//
// 返回结果:
// The same service collection so that multiple calls can be chained.
public static IServiceCollection AddDbContext<TContextService, TContextImplementation>([NotNullAttribute] this IServiceCollection serviceCollection, [CanBeNullAttribute] Action<DbContextOptionsBuilder> optionsAction = null, ServiceLifetime contextLifetime = ServiceLifetime.Scoped, ServiceLifetime optionsLifetime = ServiceLifetime.Scoped) where TContextImplementation : DbContext, TContextService;
//
// 摘要:
// Registers the given context as a service in the Microsoft.Extensions.DependencyInjection.IServiceCollection.
// You use this method when using dependency injection in your application, such
// as with ASP.NET. For more information on setting up dependency injection, see
// http://go.microsoft.com/fwlink/?LinkId=526890.
//
// 参数:
// serviceCollection:
// The Microsoft.Extensions.DependencyInjection.IServiceCollection to add services
// to.
//
// contextLifetime:
// The lifetime with which to register the DbContext service in the container.
//
// optionsLifetime:
// The lifetime with which to register the DbContextOptions service in the container.
//
// 类型参数:
// TContext:
// The type of context to be registered.
//
// 返回结果:
// The same service collection so that multiple calls can be chained.
public static IServiceCollection AddDbContext<TContext>([NotNullAttribute] this IServiceCollection serviceCollection, ServiceLifetime contextLifetime, ServiceLifetime optionsLifetime = ServiceLifetime.Scoped) where TContext : DbContext;
//
// 摘要:
// Registers the given context as a service in the Microsoft.Extensions.DependencyInjection.IServiceCollection.
// You use this method when using dependency injection in your application, such
// as with ASP.NET. For more information on setting up dependency injection, see
// http://go.microsoft.com/fwlink/?LinkId=526890.
//
// 参数:
// serviceCollection:
// The Microsoft.Extensions.DependencyInjection.IServiceCollection to add services
// to.
//
// contextLifetime:
// The lifetime with which to register the DbContext service in the container.
//
// optionsLifetime:
// The lifetime with which to register the DbContextOptions service in the container.
//
// 类型参数:
// TContextService:
// The class or interface that will be used to resolve the context from the container.
//
// TContextImplementation:
// The concrete implementation type to create.
//
// 返回结果:
// The same service collection so that multiple calls can be chained.
public static IServiceCollection AddDbContext<TContextService, TContextImplementation>([NotNullAttribute] this IServiceCollection serviceCollection, ServiceLifetime contextLifetime, ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
where TContextService : class
where TContextImplementation : DbContext, TContextService;
//
// 摘要:
// Registers the given context as a service in the Microsoft.Extensions.DependencyInjection.IServiceCollection.
// You use this method when using dependency injection in your application, such
// as with ASP.NET. For more information on setting up dependency injection, see
// http://go.microsoft.com/fwlink/?LinkId=526890.
// This overload has an optionsAction that provides the applications System.IServiceProvider.
// This is useful if you want to setup Entity Framework to resolve its internal
// services from the primary application service provider. By default, we recommend
// using the other overload, which allows Entity Framework to create and maintain
// its own System.IServiceProvider for internal Entity Framework services.
//
// 参数:
// serviceCollection:
// The Microsoft.Extensions.DependencyInjection.IServiceCollection to add services
// to.
//
// optionsAction:
// An optional action to configure the Microsoft.EntityFrameworkCore.DbContextOptions
// for the context. This provides an alternative to performing configuration of
// the context by overriding the Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// method in your derived context.
// If an action is supplied here, the Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// method will still be run if it has been overridden on the derived context. Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// configuration will be applied in addition to configuration performed here.
// In order for the options to be passed into your context, you need to expose a
// constructor on your context that takes Microsoft.EntityFrameworkCore.DbContextOptions`1
// and passes it to the base constructor of Microsoft.EntityFrameworkCore.DbContext.
//
// contextLifetime:
// The lifetime with which to register the DbContext service in the container.
//
// optionsLifetime:
// The lifetime with which to register the DbContextOptions service in the container.
//
// 类型参数:
// TContext:
// The type of context to be registered.
//
// 返回结果:
// The same service collection so that multiple calls can be chained.
public static IServiceCollection AddDbContext<TContext>([NotNullAttribute] this IServiceCollection serviceCollection, [CanBeNullAttribute] Action<IServiceProvider, DbContextOptionsBuilder> optionsAction, ServiceLifetime contextLifetime = ServiceLifetime.Scoped, ServiceLifetime optionsLifetime = ServiceLifetime.Scoped) where TContext : DbContext;
//
// 摘要:
// Registers the given context as a service in the Microsoft.Extensions.DependencyInjection.IServiceCollection.
// You use this method when using dependency injection in your application, such
// as with ASP.NET. For more information on setting up dependency injection, see
// http://go.microsoft.com/fwlink/?LinkId=526890.
// This overload has an optionsAction that provides the applications System.IServiceProvider.
// This is useful if you want to setup Entity Framework to resolve its internal
// services from the primary application service provider. By default, we recommend
// using the other overload, which allows Entity Framework to create and maintain
// its own System.IServiceProvider for internal Entity Framework services.
//
// 参数:
// serviceCollection:
// The Microsoft.Extensions.DependencyInjection.IServiceCollection to add services
// to.
//
// optionsAction:
// An optional action to configure the Microsoft.EntityFrameworkCore.DbContextOptions
// for the context. This provides an alternative to performing configuration of
// the context by overriding the Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// method in your derived context.
// If an action is supplied here, the Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// method will still be run if it has been overridden on the derived context. Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// configuration will be applied in addition to configuration performed here.
// In order for the options to be passed into your context, you need to expose a
// constructor on your context that takes Microsoft.EntityFrameworkCore.DbContextOptions`1
// and passes it to the base constructor of Microsoft.EntityFrameworkCore.DbContext.
//
// contextLifetime:
// The lifetime with which to register the DbContext service in the container.
//
// optionsLifetime:
// The lifetime with which to register the DbContextOptions service in the container.
//
// 类型参数:
// TContextService:
// The class or interface that will be used to resolve the context from the container.
//
// TContextImplementation:
// The concrete implementation type to create.
//
// 返回结果:
// The same service collection so that multiple calls can be chained.
public static IServiceCollection AddDbContext<TContextService, TContextImplementation>([NotNullAttribute] this IServiceCollection serviceCollection, [CanBeNullAttribute] Action<IServiceProvider, DbContextOptionsBuilder> optionsAction, ServiceLifetime contextLifetime = ServiceLifetime.Scoped, ServiceLifetime optionsLifetime = ServiceLifetime.Scoped) where TContextImplementation : DbContext, TContextService;
//
// 摘要:
// Registers the given context as a service in the Microsoft.Extensions.DependencyInjection.IServiceCollection
// and enables DbContext pooling. Instance pooling can increase throughput in high-scale
// scenarios such as web servers by re-using DbContext instances, rather than creating
// new instances for each request. You use this method when using dependency injection
// in your application, such as with ASP.NET. For more information on setting up
// dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890.
//
// 参数:
// serviceCollection:
// The Microsoft.Extensions.DependencyInjection.IServiceCollection to add services
// to.
//
// optionsAction:
// A required action to configure the Microsoft.EntityFrameworkCore.DbContextOptions
// for the context. When using context pooling, options configuration must be performed
// externally; Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// will not be called.
//
// poolSize:
// Sets the maximum number of instances retained by the pool.
//
// 类型参数:
// TContext:
// The type of context to be registered.
//
// 返回结果:
// The same service collection so that multiple calls can be chained.
public static IServiceCollection AddDbContextPool<TContext>([NotNullAttribute] this IServiceCollection serviceCollection, [NotNullAttribute] Action<DbContextOptionsBuilder> optionsAction, int poolSize = ) where TContext : DbContext;
//
// 摘要:
// Registers the given context as a service in the Microsoft.Extensions.DependencyInjection.IServiceCollection
// and enables DbContext pooling. Instance pooling can increase throughput in high-scale
// scenarios such as web servers by re-using DbContext instances, rather than creating
// new instances for each request. You use this method when using dependency injection
// in your application, such as with ASP.NET. For more information on setting up
// dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890.
//
// 参数:
// serviceCollection:
// The Microsoft.Extensions.DependencyInjection.IServiceCollection to add services
// to.
//
// optionsAction:
// A required action to configure the Microsoft.EntityFrameworkCore.DbContextOptions
// for the context. When using context pooling, options configuration must be performed
// externally; Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// will not be called.
//
// poolSize:
// Sets the maximum number of instances retained by the pool.
//
// 类型参数:
// TContextService:
// The class or interface that will be used to resolve the context from the container.
//
// TContextImplementation:
// The concrete implementation type to create.
//
// 返回结果:
// The same service collection so that multiple calls can be chained.
public static IServiceCollection AddDbContextPool<TContextService, TContextImplementation>([NotNullAttribute] this IServiceCollection serviceCollection, [NotNullAttribute] Action<DbContextOptionsBuilder> optionsAction, int poolSize = )
where TContextService : class
where TContextImplementation : DbContext, TContextService;
//
// 摘要:
// Registers the given context as a service in the Microsoft.Extensions.DependencyInjection.IServiceCollection
// and enables DbContext pooling. Instance pooling can increase throughput in high-scale
// scenarios such as web servers by re-using DbContext instances, rather than creating
// new instances for each request. You use this method when using dependency injection
// in your application, such as with ASP.NET. For more information on setting up
// dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890.
// This overload has an optionsAction that provides the applications System.IServiceProvider.
// This is useful if you want to setup Entity Framework to resolve its internal
// services from the primary application service provider. By default, we recommend
// using the other overload, which allows Entity Framework to create and maintain
// its own System.IServiceProvider for internal Entity Framework services.
//
// 参数:
// serviceCollection:
// The Microsoft.Extensions.DependencyInjection.IServiceCollection to add services
// to.
//
// optionsAction:
// A required action to configure the Microsoft.EntityFrameworkCore.DbContextOptions
// for the context. When using context pooling, options configuration must be performed
// externally; Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// will not be called.
//
// poolSize:
// Sets the maximum number of instances retained by the pool.
//
// 类型参数:
// TContext:
// The type of context to be registered.
//
// 返回结果:
// The same service collection so that multiple calls can be chained.
public static IServiceCollection AddDbContextPool<TContext>([NotNullAttribute] this IServiceCollection serviceCollection, [NotNullAttribute] Action<IServiceProvider, DbContextOptionsBuilder> optionsAction, int poolSize = ) where TContext : DbContext;
//
// 摘要:
// Registers the given context as a service in the Microsoft.Extensions.DependencyInjection.IServiceCollection
// and enables DbContext pooling. Instance pooling can increase throughput in high-scale
// scenarios such as web servers by re-using DbContext instances, rather than creating
// new instances for each request. You use this method when using dependency injection
// in your application, such as with ASP.NET. For more information on setting up
// dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890.
// This overload has an optionsAction that provides the applications System.IServiceProvider.
// This is useful if you want to setup Entity Framework to resolve its internal
// services from the primary application service provider. By default, we recommend
// using the other overload, which allows Entity Framework to create and maintain
// its own System.IServiceProvider for internal Entity Framework services.
//
// 参数:
// serviceCollection:
// The Microsoft.Extensions.DependencyInjection.IServiceCollection to add services
// to.
//
// optionsAction:
// A required action to configure the Microsoft.EntityFrameworkCore.DbContextOptions
// for the context. When using context pooling, options configuration must be performed
// externally; Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder)
// will not be called.
//
// poolSize:
// Sets the maximum number of instances retained by the pool.
//
// 类型参数:
// TContextService:
// The class or interface that will be used to resolve the context from the container.
//
// TContextImplementation:
// The concrete implementation type to create.
//
// 返回结果:
// The same service collection so that multiple calls can be chained.
public static IServiceCollection AddDbContextPool<TContextService, TContextImplementation>([NotNullAttribute] this IServiceCollection serviceCollection, [NotNullAttribute] Action<IServiceProvider, DbContextOptionsBuilder> optionsAction, int poolSize = )
where TContextService : class
where TContextImplementation : DbContext, TContextService;
}

 2. 测试案例

  在EF上下文的构造函数中生成一个Guid,如果是单例的,构造函数只会被调用一次,我们通过比较两个上下文是否相等 或者 比较单次、多次请求中Guid的值是否相同来验证依赖注入的上下文的各种生命周期。

         public EFDB01Context context1;
public EFDB01Context context2;
public FirstController(EFDB01Context db1, EFDB01Context db2)
{
context1 = db1;
context2 = db2;
}
/// <summary>
/// 生命周期测试
/// </summary>
public IActionResult TestLifeTime()
{
//测试方法一(判断两个上下文是否完全相同)
bool isSame1 = object.ReferenceEquals(context1,context2);
ViewBag.isSame = isSame1; //测试方法二(通过多次请求来判断Guid值是否相等)
ViewBag.MyGuid1 = context1.myGuid;
ViewBag.MyGuid2 = context2.myGuid; return View();
}

(1).将参数设置为Singleton: 每次请求的context1和context2的值相等,单次请求和多次请求MyGuid1、MyGuid2的值均相等,从而证明是全局单例的。

(2).将参数设置为Scoped:每次请求的context1和context2的值相等,单次请求中MyGuid1和MyGuid2的值相等,多次请求的情况下,每次产生的MyGuid1之间均不相同, 每次产生的MyGuid2之间均不相同,从而证明是请求内单例的。

(3).将参数设置为Transient:每次请求的context1和context2的值不相等,单次请求中MyGuid1和MyGuid2的值也不相等,多次请求的情况下,每次产生的MyGuid1之间均不相同, 每次产生的MyGuid2之间均不相同,从而证明是瞬时的。

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

第三节:EF Core上下文DbContext相关配置和生命周期的更多相关文章

  1. EF Core中DbContext可以被Dispose多次

    我们知道,在EF Core中DbContext用完后要记得调用Dispose方法释放资源.但是其实DbContext可以多次调用Dispose方法,虽然只有第一次Dispose会起作用,但是DbCon ...

  2. vue基本配置和生命周期

    Vue的实例是Vue框架的入口,其实也就是前端的ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进行对整个Vue实例生成.编译.挂着. ...

  3. EF Core 中DbContext不会跟踪聚合方法和Join方法返回的结果,及FromSql方法使用讲解

    EF Core中: 如果调用Queryable.Count等聚合方法,不会导致DbContext跟踪(track)任何实体. 此外调用Queryable.Join方法返回的匿名类型也不会被DbCont ...

  4. Java Servlet(二):servlet配置及生命周期相关(jdk7+tomcat7+eclipse)

    该篇文章记录了Servlet配置相关用法及Servlet在Servlet容器中生命周期方法. Tomcat是一个Servlet容器: 1.Servlet容器管理了Servlet的整个生命周期,并调用s ...

  5. 五 Spring的配置:Bean的配置,生命周期和作用范围

    Bean相关的配置: <bean>标签的id和name的配置: id:使用了约束中的唯一约束,里面不能出现特殊字符 name:没有使用唯一约束,理论上可以重复,实际上开发不行,里面可以出现 ...

  6. Servlet配置及生命周期

    1.设置Ecilipse快捷  file new 2.创建Servlet程序 1). 创建一个 Servlet 接口的实现类.              public class HelloServl ...

  7. servlet配置及其生命周期

    servlet配置: 在web.xml中,首先向服务器注册一个servlet.在<servlet>标签下 给定一个servlet名字,这个servlet-name是我们自己用的,方便我们用 ...

  8. maven基础--下载安装配置命令生命周期

    maven apache 公司开源项目,项目构建工具 好处: 项目小 坐标:公司名称+项目名称+版本信息 通过坐标去 仓库查找jar包 maven的两大核心: *赖管理:对jar包管理过程. 项目构建 ...

  9. .NET Framework、.NET Core 和 .NET 5+ 的产品生命周期

    本文整理记录了 .NET Framework..NET Core 和 .NET 各个版本的产品支持周期和操作系统兼容性. 早于 .NET Framework 2.0 和 .NET Core 2.1 的 ...

随机推荐

  1. find、locate、whereis、which和type

    1. find $ find . -name '*' 2. locate 很快速的搜寻档案系统内是否有指定的档案,比find要快很多 其方法是先建立一个包括系统内所有档案名称及路径的资料库,之后当寻找 ...

  2. 05、ip划分+网络配置+虚拟化基础+基本路由

    -- IP   IANA (Internet Assigned Numbers Authority) ,Internet号分配机构.负责对IP地 址分配规划以及对TCP/UDP公共服务的端口定义.国际 ...

  3. 【HttpServlet】HttpServlet类

    创建时间:6.15 HttpServlet 但在实际开发中,我们不会直接去实现Servlet接口,因为那样需要覆盖的方法太多,    我们一般创建类继承HttpServlet 实现步骤: 1)创建类继 ...

  4. Wpf DataGrid动态添加列,行数据(二)

    这是第二中方法,可直接绑定,我这里只是做出了一种思路,并不是最完美. 这里注意一下,因为我里面引用了MVVMLight,所以可能代码不是复制过去就能用了的. 样式也是,所以复制过去看不是我贴出来的界面 ...

  5. 从架构开始谈dubbo(一)

    架构发展史 一.单体应用架构      当网站流量很小时,所有的功能写在一个项目中,打包部署在tomcat中.          例如:公司管理系统,超市的收银系统         也可以将单体应用部 ...

  6. mysql在windows(含客户端工具)及linux(yum)环境下安装

    下载 地址:https://dev.mysql.com/downloads/ windows安装包下载 linux安装包下载 https://dev.mysql.com/downloads/mysql ...

  7. 06-numpy-笔记-shape

    shape 是返回 np.mat 的形状的. 1. 作为 mat 的成员变量,a.shape 2. 作为 np 的成员函数,np.shape >>> import numpy as ...

  8. VSS 使用方法

    VSS 的全称为 Visual Source Safe .作为 Microsoft Visual Studio 的一名成员,它主要任务就是负责项目文件的管理,几乎可以适用任何软件项目.管理软件开发中各 ...

  9. JDOJ 1606 数字三角形

    JDOJ 1606: 数字三角形 JDOJ传送门 Description 输入n,输出n的数字三角形 见样例 Input n Output n的数字三角形 Sample Input 4 Sample ...

  10. .Net反射-基础2-BindingFlags参数

    BindingFlags参数用于指定反射查找的范围在调用下列方法时会用到BindingFlags参数 // 调用方法. InvokeMethod // 创建实例. CreateInstance // ...