数据库设计
名称:RaoShop
表:Product
列 | 类型 | 描述 |
---|---|---|
Id | int | 编号 |
ProductName | varchar(50) | 产品名 |
Price | money | 价格 |
Quantity | int | 库存 |
CategoryId | int | 分类编号 |
表:Category
列 | 类型 | 描述 |
---|---|---|
Id | int | 编号 |
CategoryName | varchar(50) | 分类名 |
Description | varchar(500) | 描述 |
数据库优先
使用EFCore实现数据操作常用的Nuget安装包如下:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Tools
由数据库生成DbContext上下文通过以下命令实现。
Scaffold-DbContext -Connection "server=.;uid=sa;pwd=123;database=xxdb;TrustServerCertificate=true" Microsoft.EntityFrameworkCore.SqlServer -outputdir "Models"
将DbContext类中生成的代码注释掉,并在Program.cs文件中配置。
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
// => optionsBuilder.UseSqlServer("server=.;uid=sa;pwd=123;database=raoshop;TrustServerCertificate=true");
在Program.cs中添加DbContext服务,并配置数据库连接语句。
//注册一个上下文服务
builder.Services.AddDbContext<RaoshopContext>(options => {
//从配置文件中读取连接字符串
var constr = builder.Configuration.GetConnectionString("constr");
options.UseSqlServer(constr);
});
配置文件结构如下:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"constr": "server=.;uid=sa;pwd=123;database=raoshop;TrustServerCertificate=true"
}
}
现在可以在控制器中通过注入使用上下文了。
using DbFirstDemo.Models;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace DbFirstDemo.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly RaoshopContext rc; //注入上下文
public HomeController(ILogger<HomeController> logger, RaoshopContext rc)
{
_logger = logger;
this.rc = rc;
}
[HttpGet]
public IActionResult Index()
{
ViewBag.list = rc.Categories.ToList();
ViewBag.products = rc.Products.ToList();
return View();
}
}
}
代码优先
创建AspNet Core项目
添加一下包:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Tools
编写实体类
//分类模型
public class Category
{
public int Id { get; set; }
public string CategoryName { get; set; }
public string? Description { get; set; }
//导航属性
public virtual List<Product> Products { get; set; }
}
//产品模型
public class Product
{
public int Id { get; set; }
public string ProductName { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
public int CategoryId { get; set; }
//导航属性
public virtual Category Category { get; set; }
}
分别为它们编写fluent api类,用于完成一些配置。
注意: 配置优先级为:fluent api 最高、属性注释 其次、约定 最低。
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
//分类模型配置
public class CategoryConfig : IEntityTypeConfiguration<Category>
{
public void Configure(EntityTypeBuilder<Category> builder)
{
builder.ToTable("Categories");
builder.HasKey(x => x.Id);
builder.Property(x => x.CategoryName).HasMaxLength(20);
}
}
//产品模型配置
public class ProductConfig : IEntityTypeConfiguration<Product>
{
public void Configure(EntityTypeBuilder<Product> builder)
{
builder.ToTable("Products");
builder.Property(p => p.Price).HasPrecision(18, 2);
builder.Property(p => p.ProductName).HasMaxLength(20);
builder.HasOne(p => p.Category).WithMany(c => c.Products).HasForeignKey(p => p.CategoryId);
}
}
编写DbContext上下文类
using Microsoft.EntityFrameworkCore;
namespace CodeFirstDemo.Models
{
public class RSContext : DbContext
{
public RSContext()
{}
//继承父类的配置
public RSContext(DbContextOptions<RSContext> options): base(options)
{}
//应用模型类配置
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//在当前程序集中找到所有继承了IEntityTypeConfiguration接口的类型,应用它的配置
modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
}
//实体映射
public DbSet<Category> Categories { get; set; }
public DbSet<Product> Products { get; set; }
}
}
最后记得在Program.cs中注册服务。
builder.Services.AddDbContext<RSContext>(options => {
//同之前,读取配置文件中的连接字符串
var constr = builder.Configuration.GetConnectionString("constr");
options.UseSqlServer(constr);
});
注意:
通过Add-Migration命令生成迁移 ,"initDB"表示本次迁移的名称
Add-Migration initDB
使用update-database同步更新到数据库
update-database
现在可以在控制器中注入上下文并使用了。(同上,略)