• EF Core 基础知识


    数据库连接字符串

    在 ASP.NET Core 添加配置片段:

    {
      "ConnectionStrings": {
        "BloggingDatabase": "Server=(localdb)\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;"
      }
    }
    

    然后,配置对应的DbContext:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<BloggingContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("BloggingDatabase")));
    }
    

    日志记录

    EF Core 默认会与 ASP.NET Core的日志提供程序一起工作,只需要使用AddDbContextAddDbContextPool添加服务即可。

    除此之外,还可以手工添加日志记录。

    首先,创建LoggerFactory的单例:

    public static readonly LoggerFactory MyLoggerFactory
        = new LoggerFactory(new[] {new ConsoleLoggerProvider((_, __) => true, true)});
    

    然后,通过DbContextOptionsBuilder注册此单例:

    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");
    

    如果你只想记录想要的日志,例如数据操作语句,可以在ILoggerProvider中进行配置:

    public static readonly LoggerFactory MyLoggerFactory
        = new LoggerFactory(new[]
        {
            new ConsoleLoggerProvider((category, level)
                => category == DbLoggerCategory.Database.Command.Name
                   && level == LogLevel.Information, true)
        });
    

    配置弹性连接

    EF Core 可以根据不同的数据库失败,制定不同的执行策略,例如故障自动重试等。

    针对SQL Server,它知道可以重试的异常类型,并且具有合理的默认值的最大重试,重试次数等之间的延迟。

    配置如下:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseSqlServer(
                @"Server=(localdb)mssqllocaldb;Database=EFMiscellanous.ConnectionResiliency;Trusted_Connection=True;ConnectRetryCount=0",
                options => options.EnableRetryOnFailure());
    }
    

    也可在Startup中配置:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<PicnicContext>(
            options => options.UseSqlServer(
                "<connection string>",
                providerOptions => providerOptions.EnableRetryOnFailure()));
    }
    

    你也可以自定义执行策略:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseMyProvider(
                "<connection string>",
                options => options.ExecutionStrategy(...));
    }
    

    自动重试与事物

    对于执行自动重试策略来说,每一次调用context.SaveChanges()方法将会当做一个重试单元。如果你的事物中有多个SaveChanges操作,配置的自动重试策略将会抛出异常,解决方法是使用委托来手动调用执行策略。代码如下:

    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();
                }
            }
        });
    }
    

    此方法同样适用于环境事物:

    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();
                }
            }
        });
    }
    

    自动重试策略需要考虑幂等性问题,防止数据添加重复等误操作。EF Core 引入了一种状态检查机制,可以帮助我们实现是否执行成功的检测:

    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配置项

    DbContext必须有DbContextOptions实例能,Options的作用如下:

    • 配置数据库提供程序
    • 连接字符串
    • 数据库提供程序级别的可选项
    • EF Core级别的可选项

    可以通过构造函数添加Options:

    public class BloggingContext : DbContext
    {
        public BloggingContext(DbContextOptions<BloggingContext> options)
            : base(options)
        { }
    
        public DbSet<Blog> Blogs { get; set; }
    }
    

    也可以通过OnConfiguring方法进行配置:

    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite("Data Source=blog.db");
        }
    }
    

    使用依赖注入DbContext时,需要构造函数的方式进行配置,并在Startup中配置DbContext:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<BloggingContext>(options => options.UseSqlite("Data Source=blog.db"));
    }
    

    避免多线程操作

    EF Core 提供了async/await操作,但是这是一个语法糖,它并不支持并行操作,这是由于数据库连接的特性限制的,因此我们应避免针对同一个Context执行任何并行操作。

    参考文档

    参考微软 EF Core 使用文档,详情:

  • 相关阅读:
    第123讲:Hadoop集群管理之Namenode目录元数据结构详解学习笔记
    看待类和对象/C++的访问修饰符的作用
    c++之 reference vs point转
    关于 《C++网络编程+卷1+运用ACE和模式消除复杂性》的源码及例子
    C++之 new转
    第二次作业案例分析
    第一次作业四则运算
    【博客观后感】
    hello
    hlt指令
  • 原文地址:https://www.cnblogs.com/youring2/p/11144865.html
Copyright © 2020-2023  润新知