深圳外貿(mào)網(wǎng)站開發(fā)建設網(wǎng)絡營銷出來可以干什么工作
目錄
分層項目中EF Core的用法
數(shù)據(jù)庫的配置
數(shù)據(jù)庫遷移
步驟匯總
注意:
批量注冊上下文
分層項目中EF Core的用法
- 創(chuàng)建一個.NET類庫項目BooksEFCore,放實體等類。
- NuGet:Microsoft.EntityFrameworkCore.Relational
- BooksEFCore中增加實體類Book和配置類。
數(shù)據(jù)庫的配置
- 上下文類MyDbContext :為什么正式項目中最好不要在MyDbContext寫數(shù)據(jù)庫配置(連接不同的DB甚至不同類型的DB)。盡量數(shù)據(jù)庫配置的代碼寫到ASP.NET Core項目中。不重寫OnConfiguring方法,而是為MyDbContext類的構(gòu)造方法增加DbContextOptions<MyDbContext>參數(shù)。在ASP.NET Core項目對DbContextOptions的配置。
- 創(chuàng)建ASP.NET Core項目,添加對“BooksEFCore”項目的引用。NuGet安裝Microsoft.EntityFrameworkCore.SqlServer。
- 配置文件、配置代碼等放到ASP.NET Core項目中。
MyDbContext:
public class MyDbContext : DbContext
{public DbSet<Book> Books { get; set; }public MyDbContext(DbContextOptions<MyDbContext> options) : base(options){}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}
}secrets.json:
{"ConnStr": "Data Source=.;Initial Catalog=demo1;Integrated Security=SSPI;TrustServerCertificate=true;"
}Program.cs:
builder.Services.AddDbContext<MyDbContext>(opt =>
{string connStr = builder.Configuration.GetSection("ConnStr").Value;opt.UseSqlServer(connStr);
});Controller:
private readonly MyDbContext dbCtx;
public TestController(MyDbContext dbCtx)
{this.dbCtx = dbCtx;
}
數(shù)據(jù)庫遷移
- 不用研究多項目中Add-Migration的細節(jié)。實用的方案:編寫實現(xiàn)IDesignTimeDbContextFactory接口的類,把配置放到里面,反正是開發(fā)環(huán)境用而已。
- 可以把連接字符串配置到環(huán)境變量中,不過MyDesignTimeDbContextFactory中很難使用IConfiguration來讀取配置系統(tǒng),可以直接用Environment.GetEnvironmentVariable() 讀取環(huán)境變量。
- 數(shù)據(jù)庫遷移腳本要生成到BooksEFCore中,因此為這個項目安裝Microsoft.EntityFrameworkCore.Tools、Microsoft.EntityFrameworkCore.SqlServer。然后把BooksEFCore設置為啟動項目,并且在【程序包管理器控制臺】中也選中BooksEFCore項目后,執(zhí)行Add-Migration和Update-Database
internal class MyDesignTimeDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{//開發(fā)時(Add-Migration、Update-Database等)運行的數(shù)據(jù)庫上下文工廠public MyDbContext CreateDbContext(string[] args){DbContextOptionsBuilder<MyDbContext> optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();string connStr = Environment.GetEnvironmentVariable("ConnStr");optionsBuilder.UseSqlServer(connStr);MyDbContext dbCtx = new MyDbContext(optionsBuilder.Options);return dbCtx;}
}
步驟匯總
- 建類庫項目,放實體類、DbContext、配置類等;DbContext中不配置數(shù)據(jù)庫連接,而是為DbContext增加一個DbContextOptions類型的構(gòu)造函數(shù)。
- EFCore項目安裝對應數(shù)據(jù)庫的EFCore Provider
- asp.net core項目引用EFCore項目,并且通過AddDbContext來注入DbContext及對DbContext進行配置。
- Controller中就可以注入DbContext類使用了。
- 讓開發(fā)環(huán)境的Add-Migration知道連接哪個數(shù)據(jù)庫,在EFCore項目中創(chuàng)建一個實現(xiàn)了IDesignTimeDbContextFactory的類。并且在CreateDbContext返回一個連接開發(fā)數(shù)據(jù)庫的DbContext。
如果不在乎連接字符串被上傳到Git,就可以把連接字符串直接寫死到CreateDbContext;如果在乎,那么CreateDbContext里面很難讀取到VS中通過簡單的方法設置的環(huán)境變量,所以必須把連接字符串配置到Windows的正式的環(huán)境變量中,然后再 Environment.GetEnvironmentVariable讀取。 - 正常執(zhí)行Add-Migration、Update-Database遷移就行了。需要把EFCore項目設置為啟動項目,并且在【程序包管理器控制臺】中也要選中EFCore項目,并且安裝Microsoft.EntityFrameworkCore.SqlServer、Microsoft.EntityFrameworkCore.Tools
注意:
配置完環(huán)境變量需重啟VS
批量注冊上下文
如果項目采用小上下文策略,在項目中可能就存在多個上下文類,需要手動調(diào)用AddDbContext方法注冊,如果上下文連接的是同一個數(shù)據(jù)庫,可以采用反射的方式掃描程序集中所有的上下文,然后為它們逐個調(diào)用AddDbContext注冊。
Add-Migration xxx -Context DbContext名
Update-Database?-Context DbContext名
Install-Package Zack.Infrastructure
//var asms=new Assembly[] {Assembly.Load("EFCoreBooks") };
var asms= ReflectionHelper.GetAllReferencedAssemblies();
builder.Services.AddAllDbContexts(opt =>
{string connStr = builder.Configuration.GetSection("ConnStr").Value;opt.UseSqlServer(connStr);
}, asms);public record Person
{public long Id { get; set; }public string Name { get; set; }public int Age { get; set; }public string Address { get; set; }
}public class PersonDbContext : DbContext
{public DbSet<Person> Persons { get; set; }public PersonDbContext(DbContextOptions<PersonDbContext> options) : base(options){}
}internal class PersonDesignTimeDbContextFactory : IDesignTimeDbContextFactory<PersonDbContext>
{public PersonDbContext CreateDbContext(string[] args){DbContextOptionsBuilder<PersonDbContext> optionsBuilder = new DbContextOptionsBuilder<PersonDbContext>();string connStr = Environment.GetEnvironmentVariable("ConnStr");optionsBuilder.UseSqlServer(connStr);PersonDbContext dbCtx = new PersonDbContext(optionsBuilder.Options);return dbCtx;}
}