EF Code First关系规则及配置
1、一对多关系
关系表:
Category 分类表
Product 产品表
分类与产品之间的一对多关系
1>、产品实体类不指定外键属性
Domain中类定义:
Category.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 using System.ComponentModel.DataAnnotations; 7 8 namespace Northwind.Domain.Entities 9 {10 public class Category11 {12 /// <summary>13 /// 分类ID14 /// </summary>15 public int CategoryID { get; set; }16 17 /// <summary>18 /// 分类名称19 /// </summary>20 public string CategoryName { get; set; }21 22 /// <summary>23 /// 描述24 /// </summary>25 public string Description { get; set; }26 27 /// <summary>28 /// 图片29 /// </summary>30 public byte[] Picture { get; set; }31 32 /// <summary>33 /// 产品34 /// </summary>35 public virtual ICollection<Product> Products { get; set; }36 }37 }Product.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Northwind.Domain.Entities 7 { 8 public class Product 9 {10 /// <summary>11 /// 产品ID12 /// </summary>13 public int ProductID { get; set; }14 15 /// <summary>16 /// 产品名称17 /// </summary>18 public string ProductName { get; set; }19 20 /// <summary>21 /// 单价22 /// </summary>23 public decimal UnitPrice { get; set; }24 25 /// <summary>26 /// 库存27 /// </summary>28 public int UnitsInStock { get; set; }29 30 /// <summary>31 /// 是否售完32 /// </summary>33 public bool Discontinued { get; set; }34 35 /// <summary>36 /// 产品分类37 /// </summary>38 public virtual Category Category { get; set; }39 }40 }CategoryMap.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 using System.Data.Entity.ModelConfiguration; 7 using System.ComponentModel.DataAnnotations; 8 9 using Northwind.Domain.Entities;10 11 namespace Northwind.Domain.Mapping12 {13 public class CategoryMap : EntityTypeConfiguration<Category>14 {15 public CategoryMap()16 {17 this.ToTable("dbo.Category");18 this.HasKey(t => t.CategoryID);19 20 this.Property(t => t.CategoryName).IsRequired().HasMaxLength(15);21 this.Property(t => t.Picture).HasColumnType("image");22 }23 }24 }ProductMap.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 using System.Data.Entity.ModelConfiguration; 7 using System.ComponentModel.DataAnnotations; 8 9 using Northwind.Domain.Entities;10 11 namespace Northwind.Domain.Mapping12 {13 public class ProductMap : EntityTypeConfiguration<Product>14 {15 public ProductMap()16 {17 this.ToTable("dbo.Product");18 this.HasKey(t => t.ProductID);19 20 this.Property(t => t.ProductName).IsRequired().HasMaxLength(50);21 this.Property(t => t.UnitPrice).HasPrecision(18, 2);22 }23 }24 }Data中类定义:
NorthwindContext.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 using System.Data.Entity; 7 8 using Northwind.Domain.Entities; 9 using Northwind.Domain.Mapping;10 11 namespace Northwind.Data12 {13 public class NorthwindContext : DbContext14 {15 public DbSet<Category> Categories { get; set; }16 public DbSet<Product> Products { get; set; }17 18 protected override void OnModelCreating(DbModelBuilder modelBuilder)19 {20 modelBuilder.Configurations.Add(new CategoryMap());21 modelBuilder.Configurations.Add(new ProductMap());22 }23 }24 }App中类定义:
Program.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 using Northwind.Data; 7 using Northwind.Domain.Entities; 8 9 using System.Data.Entity;10 11 namespace Northwind.App12 {13 class Program14 {15 static void Main(string[] args)16 {17 // 数据模型改变,删除数据库重新创建。18 Database.SetInitializer(new DropCreateDatabaseIfModelChanges<NorthwindContext>());19 20 Category c = new Category() { CategoryName = "电子数码" };21 22 Product p = new Product() { ProductName = "笔记本电脑", UnitPrice = 4500.00m, Category = c, UnitsInStock = 100, Discontinued = false };23 using (NorthwindContext db = new NorthwindContext())24 {25 db.Categories.Add(c);26 db.Products.Add(p);27 28 db.SaveChanges();29 }30 31 Console.WriteLine("Finish");32 Console.ReadKey();33 }34 }35 }运行之后生成的数据库结构
2>、产品实体类中指定外键属性
修改Domain中Product.cs代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Northwind.Domain.Entities 7 { 8 public class Product 9 {10 /// <summary>11 /// 产品ID12 /// </summary>13 public int ProductID { get; set; }14 15 /// <summary>16 /// 产品名称17 /// </summary>18 public string ProductName { get; set; }19 20 /// <summary>21 /// 单价22 /// </summary>23 public decimal UnitPrice { get; set; }24 25 /// <summary>26 /// 库存27 /// </summary>28 public int UnitsInStock { get; set; }29 30 /// <summary>31 /// 是否售完32 /// </summary>33 public bool Discontinued { get; set; }34 35 /// <summary>36 /// 分类ID37 /// </summary>38 public int CategoryID { get; set; }39 40 /// <summary>41 /// 产品分类42 /// </summary>43 public virtual Category Category { get; set; }44 }45 }运行之后生成的数据库中表结构如下:
默认的外键规则:[Target Type Key Name], [Target Type Name] + [Target Type Key Name], 或者 [Navigation
Property Name] + [Target Type Key Name]。
3>、使用Data Annotations指定外键属性
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 using System.ComponentModel.DataAnnotations; 7 8 namespace Northwind.Domain.Entities 9 {10 public class Product11 {12 /// <summary>13 /// 产品ID14 /// </summary>15 public int ProductID { get; set; }16 17 /// <summary>18 /// 产品名称19 /// </summary>20 public string ProductName { get; set; }21 22 /// <summary>23 /// 单价24 /// </summary>25 public decimal UnitPrice { get; set; }26 27 /// <summary>28 /// 库存29 /// </summary>30 public int UnitsInStock { get; set; }31 32 /// <summary>33 /// 是否售完34 /// </summary>35 public bool Discontinued { get; set; }36 37 /// <summary>38 /// 分类ID39 /// </summary>40 public int CategoryID { get; set; }41 42 /// <summary>43 /// 产品分类44 /// </summary>45 [ForeignKey("CategoryID")]46 public virtual Category Category { get; set; }47 }48 }4>、使用Fluent指定外键属性
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 using System.Data.Entity.ModelConfiguration; 7 using System.ComponentModel.DataAnnotations; 8 9 using Northwind.Domain.Entities;10 11 namespace Northwind.Domain.Mapping12 {13 public class ProductMap : EntityTypeConfiguration<Product>14 {15 public ProductMap()16 {17 // Primary Key18 this.HasKey(t => t.ProductID);19 20 // Properties21 this.Property(t => t.ProductName).IsRequired().HasMaxLength(50);22 this.Property(t => t.UnitPrice).HasPrecision(18, 2);23 24 // Table & Column Mappings25 this.ToTable("dbo.Product");26 this.Property(t => t.ProductID).HasColumnName("ProductID");27 this.Property(t => t.ProductName).HasColumnName("ProductName");28 this.Property(t => t.UnitPrice).HasColumnName("UnitPrice");29 this.Property(t => t.UnitsInStock).HasColumnName("UnitsInStock");30 this.Property(t => t.Discontinued).HasColumnName("Discontinued");31 this.Property(t => t.CategoryID).HasColumnName("CategoryID");32 33 // Relationships34 this.HasRequired(t => t.Category)35 .WithMany(t => t.Products)36 .HasForeignKey(t => t.CategoryID)37 .WillCascadeOnDelete(false);38 }39 }40 }5>、示例代码附件
以上示例代码附件,并补充Product与Category及Supplier的两个外键关联。
Northwind-一对多外键.rar
二、多对多关系
表说明:
用户表:User
角色表:Role
用户与角色多对多,一个用户可以属于多个角色,一个角色可以有多个用户。
Domain中User.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Northwind.Domain.Entities 7 { 8 public class User 9 {10 /// <summary>11 /// 用户ID12 /// </summary>13 public int UserID { get; set; }14 15 /// <summary>16 /// 用户名17 /// </summary>18 public string UserName { get; set; }19 20 /// <summary>21 /// 密码22 /// </summary>23 public string Password { get; set; }24 25 /// <summary>26 /// 角色27 /// </summary>28 public ICollection<Role> Roles { get; set; }29 }30 }Role.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Northwind.Domain.Entities 7 { 8 public class Role 9 {10 /// <summary>11 /// 角色ID12 /// </summary>13 public int RoleID { get; set; }14 15 /// <summary>16 /// 角色名称17 /// </summary>18 public string RoleName { get; set; }19 20 /// <summary>21 /// 用户22 /// </summary>23 public virtual ICollection<User> Users { get; set; }24 }25 }UserMap.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 using System.Data.Entity.ModelConfiguration; 7 using System.ComponentModel.DataAnnotations; 8 9 using Northwind.Domain.Entities;10 11 namespace Northwind.Domain.Mapping12 {13 public class UserMap : EntityTypeConfiguration<User>14 {15 public UserMap()16 {17 // Primary Key18 this.HasKey(t => t.UserID);19 20 // Properties21 this.Property(t => t.UserName).IsRequired().HasMaxLength(50);22 this.Property(t => t.Password).IsRequired().HasMaxLength(50);23 24 // Table & Column Mappings25 this.ToTable("dbo.User");26 this.Property(t => t.UserID).HasColumnName("UserID");27 this.Property(t => t.UserName).HasColumnName("UserName");28 this.Property(t => t.Password).HasColumnName("Password");29 30 // Relationships31 this.HasMany(t => t.Roles)32 .WithMany(t => t.Users)33 .Map(t => t.MapLeftKey("RoleID").MapRightKey("UserID"));34 }35 }36 }RoleMap.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 using System.Data.Entity.ModelConfiguration; 7 using System.ComponentModel.DataAnnotations; 8 9 using Northwind.Domain.Entities;10 11 namespace Northwind.Domain.Mapping12 {13 public class RoleMap : EntityTypeConfiguration<Role>14 {15 public RoleMap()16 {17 // Primary Key18 this.HasKey(t => t.RoleID);19 20 // Properties21 this.Property(t => t.RoleName).IsRequired().HasMaxLength(50);22 23 // Table & Column Mappings24 this.ToTable("dbo.Role");25 this.Property(t => t.RoleID).HasColumnName("RoleID");26 this.Property(t => t.RoleName).HasColumnName("RoleName");27 28 // Relationships29 this.HasMany(t => t.Users)30 .WithMany(t => t.Roles)31 .Map(t => t.MapLeftKey("UserID").MapRightKey("RoleID"));32 }33 }34 }Data中NorthwindContext.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data.Entity;using Northwind.Domain.Entities;using Northwind.Domain.Mapping;namespace Northwind.Data{ public class NorthwindContext : DbContext { public DbSet<Category> Categories { get; set; } public DbSet<Product> Products { get; set; } public DbSet<Supplier> Suppliers { get; set; } public DbSet<User> Users { get; set; } public DbSet<Role> Roles { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new CategoryMap()); modelBuilder.Configurations.Add(new ProductMap()); modelBuilder.Configurations.Add(new SupplierMap()); modelBuilder.Configurations.Add(new UserMap()); modelBuilder.Configurations.Add(new RoleMap()); } }}运行成功后生成的数据表:
三、一对一关系