EF Code First关系规则及配置

Posted Avatarx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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());        }    }}运行成功后生成的数据表:

 

三、一对一关系

以上是关于EF Code First关系规则及配置的主要内容,如果未能解决你的问题,请参考以下文章

EF Code First导航属性一对一关系中注意点及配置方法

EF Code-First 学习之旅 配置一对一的关系

EF Code First学习

EF Code First 没有实体的多对多关系

EF Code First自定义数据库(服务器及数据库名)连接配置

EF Code First 学习笔记:关系