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的操作,感覺棒棒噠。

 

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