EF Core Basics

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 AddDbContextor AddDbContextPooladd 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 DbContextOptionsBuilderregistered 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:

Guess you like

Origin www.cnblogs.com/youring2/p/11144865.html