ENTITY FRAMEWORK CORE入门:二、再探EFCore的操作

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章