一、引言
这篇文章中我们讲解如何在Web项目中使用EntityFrameworkCore,并生成数据库表,这里以ASP.NET Core WebApi为例讲解。还是采用分层的结构。创建后的项目整体结构如下图所示:
项目结构:
- EFCoreWeb.API:ASP.NET Core WebApi项目,用来提供Web功能,在项目中会引用EFCoreWeb.Data。
- EFCoreWeb.Data:类库项目,基于.NET Core的类库。存放的是与EFCore相关的操作。
- EFCoreWeb.Model:类库项目,基于.NET Core的类库。存放的是实体类。
1、添加实体类
我们在EFCoreWeb.Model类库项目里面添加Student实体类:
namespace EFCoreWeb.Model
{
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public int Gender { get; set; }
}
}
2、添加Mircosoft.EntityFrameworkCore
因为要使用Student实体类,首先要在EFCoreWeb.Data项目里面添加对EFCoreWeb.Model的引用。
然后在EFCoreWeb.Data类库项目里面添加Mircosoft.EntityFrameworkCore包,直接在NuGet里面安装:
由于我们使用的是SQLServer数据库,所以我们还要安装Microsoft.EntityFrameworkCore.sqlServer包,同样也是直接在NuGet里面安装:
安装完上面的两个包以后,在EFCoreWeb.Data类库项目里面添加Mapping文件夹,用来存放Fluent API的配置文件,Student类的配置伙伴类代码如下:
using EFCoreWeb.Model; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace EFCoreWeb.Data.Mapping { /// <summary> /// Student配置伙伴类,继承自IEntityTypeConfiguration<T>泛型接口 /// </summary> public class StudentMap : IEntityTypeConfiguration<Student> { /// <summary> /// 实现接口里面的Configure方法,用来配置生成数据库表结构 /// </summary> /// <param name="builder"></param> public void Configure(EntityTypeBuilder<Student> builder) { // 设置主键 builder.HasKey(p => p.Id); // 设置生成的表名 builder.ToTable("T_Student"); // 设置Name列的最大长度 builder.Property("Name").HasMaxLength(64); // 设置Name列是必须的 builder.Property("Name").IsRequired(); } } }
添加一个Context文件夹,然后添加数据上下文类,继承自DbContext:
using EFCoreWeb.Model; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace EFCoreWeb.Data.Mapping { /// <summary> /// Student配置伙伴类,继承自IEntityTypeConfiguration<T>泛型接口 /// </summary> public class StudentMap : IEntityTypeConfiguration<Student> { /// <summary> /// 实现接口里面的Configure方法,用来配置生成数据库表结构 /// </summary> /// <param name="builder"></param> public void Configure(EntityTypeBuilder<Student> builder) { // 设置主键 builder.HasKey(p => p.Id); // 设置生成的表名 builder.ToTable("T_Student"); // 设置Name列的最大长度 builder.Property("Name").HasMaxLength(64); // 设置Name列是必须的 builder.Property("Name").IsRequired(); } } }
二、生成数据库表
这里我们使用程序包管理器控制台迁移的方式来生成数据库表。需要在EFCoreWeb.Data项目里面安装Microsoft.EntityFrameworkCore.Tools包。在EFCoreWeb.API项目里面安装Microsoft.EntityFrameworkCore.Tools、Microsoft.EntityFrameworkCore两个包。EFCoreWeb.API项目添加对EFCoreWeb.Data项目的引用。
首先在EFCoreWeb.API项目的appsettings.json文件里面添加数据库连接字符串:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "ConnectionString": { "DbConnection": "Data Source=.;Initial Catalog=EFTestDb;User ID=sa;Password=123456;" } }
在Startup类的ConfigureServices方法里面添加数据库连接:
using EFCoreWeb.Data.Context; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace EFCoreWeb.API { 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) { #region 数据库连接 services.AddDbContext<EFCoreDbContext>(options => { // options.UseSqlServer(Configuration.GetConnectionString("DbConnection")); options.UseSqlServer(Configuration.GetSection("ConnectionString").GetSection("DbConnection").Value); }); #endregion services.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
上面步骤配置完成以后,在程序包管理器控制台里面开始迁移,使用下面的命令添加迁移:
Add-Migration Init
如下图所示:
执行完命令以后就会生成迁移文件:
添加迁移之后,执行下面的命令更新数据库:
Update-Database
如下图所示:
执行完以后去查看数据库:
可以看到,表里面Name列的长度是根据代码里面设置的长度生成的,而且不为null,种子数据也插入进去了。