1、之前寫了:ENTITY FRAMEWORK CORE入門:一、初探EFCore的操作
其中講過的一些新建項目和類就不多說了,按照之前的方式新建好一個NetCoreWEB項目:EFCoreTest02,然後在解決方案中添加類庫AspEFCore.Data、AspEFCore.Domain.Model。
2、AspEFCore.Data中添加引用AspEFCore.Domain.Model以及引用 NuGet包Microsoft.EntifyFrameworkCore.SqlServer
在EFCoreTest02的項目裏面添加引用:AspEFCore.Data和AspEFCore.Domain.Model
3、在AspEFCore.Domain.Model內新建6個Model類,直接上代碼
public class City
{
/// <summary>
/// 編碼
/// </summary>
///
public City()
{
CityCompanies = new List<CityCompany>();
}
//public City()
//{
// Mayors = new List<Mayor>();
//}
public int Id { get; set; }
/// <summary>
/// 城市名稱
/// </summary>
public string Name { get; set; }
/// <summary>
/// 郵編
/// </summary>
public string AreaCode { get; set; }
/// <summary>
/// 所屬省份編碼
/// </summary>
public int ProviedId { get; set; }
/// <summary>
/// 省份
/// </summary>
public Province Province { get; set; }
public List<CityCompany> CityCompanies { get; set; }
public Mayor Mayor { get; set; }
}
public class CityCompany
{
/// <summary>
/// 城市Id
/// </summary>
public int CityId { get; set; }
/// <summary>
/// 導航屬性
/// </summary>
public City City { get; set; }
/// <summary>
///
/// </summary>
public int CompanyId { get; set; }
/// <summary>
///
/// </summary>
public Company Company { get; set; }
}
public class Company
{
public Company()
{
CityCompanies = new List<CityCompany>();
}
/// <summary>
/// 編碼
/// </summary>
public int Id { get; set; }
/// <summary>
/// 名稱
/// </summary>
public string Name { get; set; }
/// <summary>
/// 成立時間
/// </summary>
public DateTime EstablishDate { get; set; }
/// <summary>
/// 法人
/// </summary>
public string LegalPerson { get; set; }
public List<CityCompany> CityCompanies { get; set; }
}
public class Province
{
public Province()
{
Cities = new List<City>();
}
/// <summary>
/// 編碼
/// </summary>
public int Id { get; set; }
/// <summary>
/// 省份名稱
/// </summary>
public string Name { get; set; }
/// <summary>
/// 人口
/// </summary>
public int Population { get; set; }
/// <summary>
/// 城市
/// </summary>
public List<City> Cities { get; set; }
}
public enum Gender
{
/// <summary>
/// 女
/// </summary>
Female = 0,
/// <summary>
/// 男
/// </summary>
Male = 1
}
public class Mayor
{
/// <summary>
///市長Id
/// </summary>
///
public int MayorId { get; set; }
public string MayorName { get; set; }
public int CityId { get; set; }
public City City { get; set; }
}
4、AspEFCore.Data中新建類MyContext.cs
public class MyContext : DbContext
{
/// <summary>
/// 外部參數
/// </summary>
/// <param name="options">外部傳入的配置參數(這樣子的話,我們就可以通過外部來控制傳入的參數值,用以決定使用哪個數據庫)</param>
public MyContext(DbContextOptions<MyContext> options) : base(options)
{
}
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//{
// //使用本地的Windows驗證
// optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=EFCoreDemo;Trusted_Connection=True;");
// //base.OnConfiguring(optionsBuilder);
//}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//添加數據
//modelBuilder.Entity<Province>().HasData(
// new Province
// {
// Id = 20,
// Name = "福建省",
// Population = 6000
// }
// );
modelBuilder.Entity<City>()
.HasOne(x => x.Province).WithMany(x => x.Cities).HasForeignKey(x => x.ProviedId);
//配置聯合主鍵
modelBuilder.Entity<CityCompany>()
.HasKey(x => new { x.CityId, x.CompanyId });
modelBuilder.Entity<CityCompany>()
.HasOne(x => x.City).WithMany(x => x.CityCompanies).HasForeignKey(x => x.CityId);
modelBuilder.Entity<CityCompany>()
.HasOne(x => x.Company).WithMany(x => x.CityCompanies).HasForeignKey(x => x.CompanyId);
modelBuilder.Entity<Mayor>()
.HasOne(x => x.City).WithOne(x => x.Mayor).HasForeignKey<Mayor>(x => x.CityId);
}
public DbSet<City> Cities { get; set; }
public DbSet<Province> Provinces { get; set; }
public DbSet<CityCompany> CityCompanies { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<Mayor> Mayors { get; set; }
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//{
// //使用本地的Windows驗證
// optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=EFCoreDemo;Trusted_Connection=True;");
// //base.OnConfiguring(optionsBuilder);
//}
}
5、appsettings.json的設置
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Debug"
}
},
"ConnectionStrings": {
"EFCoreTest02Connection": "Server=WIN-NNQVERK2299\\MSSQL2012;Database=EFCoreTest02;Uid=sa;Pwd=123456;Trusted_Connection=True;"
},
"AllowedHosts": "*"
}
6、看一下Startup.cs的設置(到Data裏的OnModelCreating進行關聯)
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<MyContext>(
options =>
{
//獲取數據連接串
//options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), b => b.MigrationsAssembly("AspEFCore20200313")
options.UseSqlServer(Configuration.GetConnectionString("EFCoreTest02Connection")
);
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.Run(async (context) =>
{
await context.Response.WriteAsync("ckHello World");
});
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc();
}
}
7、使用 程序包管理控制檯-生成數據
1)默認項目設置成 數據Data連接(MyContext.cs) 的所在項目,將數據庫配置的(AspEFCore.Web)項目設置成啓動項
2)這裏看一個常見問題:前面在AspEFCore.Data 中引用的Microsoft.EntityFrameworkCore.SqlServer 版本爲2.2.4,後AspEFCore.Web 裏面默認有引用這個(創建項目默認引用,但是版本爲2.1.1),導致版本不符合,我就將AspEFCore.Data 的Microsoft.EntityFrameworkCore.SqlServer 降成版本2.1.1,注意使用相同的版本就可以了。
8、開始遷移
工具-Nuget包管理-程序包管理控制檯 執行:PM>Add-Migration Initial
出現了問題:出現問題就要,解決問題。
報錯內容:Your target project 'xxxxx' doesn't match your migrations assembly xxxxxxxx'. Either change your target project or change your migrations assembly.
問題解釋:當前執行遷移項目和包含DbContext程序集項目不一致,要麼更改執行遷移操作的項目,要麼修改遷移程序集。
處理方法:兩條路自己選,要麼切換到用DbContext程序集管理遷移代碼,要麼修改當前代碼以適應遷移方法。錯誤信息裏給出了一個簡單的解決方法:
Your target project 'EFCoreTest02' doesn't match your migrations assembly 'AspEFCore.Data'. Either change your target project or change your migrations assembly.
Change your migrations assembly by using DbContextOptionsBuilder. E.g. options.UseSqlServer(connection, b => b.MigrationsAssembly("EFCoreTest02")). By default, the migrations assembly is the assembly containing the DbContext.
Change your target project to the migrations project by using the Package Manager Console's Default project drop-down list, or by executing "dotnet ef" from the directory containing the migrations project.
修改Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<MyContext>(
options =>
{
//EFCoreTest02
options.UseSqlServer(Configuration.GetConnectionString("EFCoreTest02Connection"), b => b.MigrationsAssembly("EFCoreTest02")
);
});
}
修改後再次使用PM>Add-Migration Initial,操作成功。控制檯顯示我都發出來自己覈對!
PM> Add-Migration Initial
Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 2.2.2-servicing-10034 initialized 'MyContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: MigrationsAssembly=EFCoreTest02
To undo this action, use Remove-Migration.
PM> Update-Database
Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 2.2.2-servicing-10034 initialized 'MyContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: MigrationsAssembly=EFCoreTest02
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (841ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
CREATE DATABASE [EFCoreTest02];
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (673ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
IF SERVERPROPERTY('EngineEdition') <> 5
BEGIN
ALTER DATABASE [EFCoreTest02] SET READ_COMMITTED_SNAPSHOT ON;
END;
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (58ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [__EFMigrationsHistory] (
[MigrationId] nvarchar(150) NOT NULL,
[ProductVersion] nvarchar(32) NOT NULL,
CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (6ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [MigrationId], [ProductVersion]
FROM [__EFMigrationsHistory]
ORDER BY [MigrationId];
Applying migration '20200317061042_Initial'.
Microsoft.EntityFrameworkCore.Migrations[20402]
Applying migration '20200317061042_Initial'.
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [Companies] (
[Id] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
[EstablishDate] datetime2 NOT NULL,
[LegalPerson] nvarchar(max) NULL,
CONSTRAINT [PK_Companies] PRIMARY KEY ([Id])
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [Provinces] (
[Id] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
[Population] int NOT NULL,
CONSTRAINT [PK_Provinces] PRIMARY KEY ([Id])
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [Cities] (
[Id] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
[AreaCode] nvarchar(max) NULL,
[ProviedId] int NOT NULL,
CONSTRAINT [PK_Cities] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Cities_Provinces_ProviedId] FOREIGN KEY ([ProviedId]) REFERENCES [Provinces] ([Id]) ON DELETE CASCADE
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [CityCompanies] (
[CityId] int NOT NULL,
[CompanyId] int NOT NULL,
CONSTRAINT [PK_CityCompanies] PRIMARY KEY ([CityId], [CompanyId]),
CONSTRAINT [FK_CityCompanies_Cities_CityId] FOREIGN KEY ([CityId]) REFERENCES [Cities] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_CityCompanies_Companies_CompanyId] FOREIGN KEY ([CompanyId]) REFERENCES [Companies] ([Id]) ON DELETE CASCADE
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [Mayors] (
[MayorId] int NOT NULL IDENTITY,
[MayorName] nvarchar(max) NULL,
[CityId] int NOT NULL,
CONSTRAINT [PK_Mayors] PRIMARY KEY ([MayorId]),
CONSTRAINT [FK_Mayors_Cities_CityId] FOREIGN KEY ([CityId]) REFERENCES [Cities] ([Id]) ON DELETE CASCADE
);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX [IX_Cities_ProviedId] ON [Cities] ([ProviedId]);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE INDEX [IX_CityCompanies_CompanyId] ON [CityCompanies] ([CompanyId]);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE UNIQUE INDEX [IX_Mayors_CityId] ON [Mayors] ([CityId]);
Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20200317061042_Initial', N'2.2.2-servicing-10034');
Done.
PM>
數據庫和表都已經完成,就是這麼的神奇!第一次領略CodeFirst的操作,感覺棒棒噠。