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的操作,感觉棒棒哒。