在 ASP.NET Core 添加配置片斷:sql
{ "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
添加服務便可。多線程
除此以外,還能夠手工添加日誌記錄。async
首先,建立LoggerFactory的單例:ide
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中進行配置:ui
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,它知道能夠重試的異常類型,而且具備合理的默認值的最大重試,重試次數等之間的延遲。日誌
配置以下:code
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必須有DbContextOptions實例能,Options的做用以下:
能夠經過構造函數添加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 使用文檔,詳情: