前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >EF Core 基础知识

EF Core 基础知识

作者头像
拓荒者-NET
发布2019-09-23 15:35:45
7320
发布2019-09-23 15:35:45
举报

数据库连接字符串

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

代码语言:javascript
复制
{
  "ConnectionStrings": {
    "BloggingDatabase": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;"
  }
}

然后,配置对应的DbContext:

代码语言:javascript
复制
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<BloggingContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("BloggingDatabase")));
}

日志记录

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

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

首先,创建LoggerFactory的单例:

代码语言:javascript
复制
public static readonly LoggerFactory MyLoggerFactory
    = new LoggerFactory(new[] {new ConsoleLoggerProvider((_, __) => true, true)});

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

代码语言:javascript
复制
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中进行配置:

代码语言:javascript
复制
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,它知道可以重试的异常类型,并且具有合理的默认值的最大重试,重试次数等之间的延迟。

配置如下:

代码语言:javascript
复制
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(
            @"Server=(localdb)\mssqllocaldb;Database=EFMiscellanous.ConnectionResiliency;Trusted_Connection=True;ConnectRetryCount=0",
            options => options.EnableRetryOnFailure());
}

也可在Startup中配置:

代码语言:javascript
复制
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<PicnicContext>(
        options => options.UseSqlServer(
            "<connection string>",
            providerOptions => providerOptions.EnableRetryOnFailure()));
}

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

代码语言:javascript
复制
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseMyProvider(
            "<connection string>",
            options => options.ExecutionStrategy(...));
}

自动重试与事物

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

代码语言:javascript
复制
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();
            }
        }
    });
}

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

代码语言:javascript
复制
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 引入了一种状态检查机制,可以帮助我们实现是否执行成功的检测:

代码语言:javascript
复制
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:

代码语言:javascript
复制
public class BloggingContext : DbContext
{
    public BloggingContext(DbContextOptions<BloggingContext> options)
        : base(options)
    { }

    public DbSet<Blog> Blogs { get; set; }
}

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

代码语言:javascript
复制
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:

代码语言:javascript
复制
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<BloggingContext>(options => options.UseSqlite("Data Source=blog.db"));
}

避免多线程操作

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

参考文档

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-07-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据库连接字符串
  • 日志记录
  • 配置弹性连接
    • 自动重试与事物
    • DbContext配置项
    • 避免多线程操作
    • 参考文档
    相关产品与服务
    数据库
    云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档