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的日志提供程序一起工作,只需要使用AddDbContext
或AddDbContextPool
添加服务即可。
除此之外,还可以手工添加日志记录。
首先,创建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 使用文档,详情:
本文作者:拓荒者IT
本文链接:https://www.cnblogs.com/youring2/p/11144865.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
📌做了个微信公众号【拓荒者IT】,分享各种技术干货,新内容首发到公众号,欢迎关注❤️
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步