Database connection string
Adding configure fragment ASP.NET Core:
{
"ConnectionStrings": {
"BloggingDatabase": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;"
}
}
Then, the configuration corresponding DbContext:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BloggingContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("BloggingDatabase")));
}
Logging
EF Core provided by default with ASP.NET Core logging program to work with, only you need to use AddDbContext
or AddDbContextPool
add the service.
In addition, you can also manually add logging.
First, create LoggerFactory singleton:
public static readonly LoggerFactory MyLoggerFactory
= new LoggerFactory(new[] {new ConsoleLoggerProvider((_, __) => true, true)});
Then, the DbContextOptionsBuilder
registered single this Example:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLoggerFactory(MyLoggerFactory) // Warning: Do not create a new ILoggerFactory instance each time
.UseSqlServer(
@"Server=(localdb)\mssqllocaldb;Database=EFLogging;Trusted_Connection=True;ConnectRetryCount=0");
If you want to log wanted, such as data manipulation statements, can be configured in ILoggerProvider in:
public static readonly LoggerFactory MyLoggerFactory
= new LoggerFactory(new[]
{
new ConsoleLoggerProvider((category, level)
=> category == DbLoggerCategory.Database.Command.Name
&& level == LogLevel.Information, true)
});
An elastic connection
EF Core according to different databases fail to develop different execution strategies, such as auto-retry fault and so on.
For SQL Server, it knows the type of exception can be retried, and has a maximum retry reasonable default, the delay between the number of retries.
Configuration is as follows:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(
@"Server=(localdb)\mssqllocaldb;Database=EFMiscellanous.ConnectionResiliency;Trusted_Connection=True;ConnectRetryCount=0",
options => options.EnableRetryOnFailure());
}
May be disposed in the Startup:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<PicnicContext>(
options => options.UseSqlServer(
"<connection string>",
providerOptions => providerOptions.EnableRetryOnFailure()));
}
You can also customize the execution policy:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseMyProvider(
"<connection string>",
options => options.ExecutionStrategy(...));
}
Automatic retry and things
For automatic retry strategy for each call context.SaveChanges()
method will be retried as a unit. If you have multiple things SaveChanges operation, automatic retry policy configuration will throw an exception, the solution is to use a delegate to manually invoke execution policy. code show as below:
using (var db = new BloggingContext())
{
var strategy = db.Database.CreateExecutionStrategy();
strategy.Execute(() =>
{
using (var context = new BloggingContext())
{
using (var transaction = context.Database.BeginTransaction())
{
context.Blogs.Add(new Blog {Url = "http://blogs.msdn.com/dotnet"});
context.SaveChanges();
context.Blogs.Add(new Blog {Url = "http://blogs.msdn.com/visualstudio"});
context.SaveChanges();
transaction.Commit();
}
}
});
}
This method is also applicable environmental things:
using (var context1 = new BloggingContext())
{
context1.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" });
var strategy = context1.Database.CreateExecutionStrategy();
strategy.Execute(() =>
{
using (var context2 = new BloggingContext())
{
using (var transaction = new TransactionScope())
{
context2.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
context2.SaveChanges();
context1.SaveChanges();
transaction.Complete();
}
}
});
}
Automatic retry strategy needs to consider issues such as power, data is added to prevent duplication misuse. EF Core introduces a state inspection mechanism can help us achieve success in detecting whether:
using (var db = new BloggingContext())
{
var strategy = db.Database.CreateExecutionStrategy();
var blogToAdd = new Blog {Url = "http://blogs.msdn.com/dotnet"};
db.Blogs.Add(blogToAdd);
strategy.ExecuteInTransaction(db,
operation: context =>
{
context.SaveChanges(acceptAllChangesOnSuccess: false);
},
verifySucceeded: context => context.Blogs.AsNoTracking().Any(b => b.BlogId == blogToAdd.BlogId));
db.ChangeTracker.AcceptAllChanges();
}
DbContext configuration items
There can be DbContext DbContextOptions example, the following effect Options:
- Configuration database provider
- Connection String
- Database provider-level options
- EF Core-level options
Options can be added via the constructor:
public class BloggingContext : DbContext
{
public BloggingContext(DbContextOptions<BloggingContext> options)
: base(options)
{ }
public DbSet<Blog> Blogs { get; set; }
}
You can also be configured by OnConfiguring Method:
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=blog.db");
}
}
When using DbContext dependency injection, approach requires constructor configured and arranged in the Startup DbContext:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BloggingContext>(options => options.UseSqlite("Data Source=blog.db"));
}
Avoid multithreading
EF Core provides async / await the operation, but this is a syntactic sugar, it does not support parallel operations, due to the characteristics of the database connection limit, so we should avoid performing any parallel operation for the same Context.
Reference Documents
Reference Microsoft EF Core uses the document, the details: