EFCodeFirst关系映射约定

EFCodeFirst
关系映射约定

默认多重关系的一些约定规则:

1.一对多关系

两个类中分别包含一个引用和一个集合属性。

两个类中一个类包含另一个类的引用属性。

两个类中一个类包含另一个类的集合属性。

2.多对多关系

两个类分别包含对方的一个集合属性。

3.一对一关系

两个类分别包含对方的一个引用属性。

1.外键列名默认约定

3种外键列名的约定方式是:

  • [Target Type Key Name],[目标类型的键名]
  • [Target Type Name] + [Target Type Key Name],[目标类型名称]+[目标类型键名称]
  • [Navigation Property Name] + [Target Type Key Name],[引用属性名称]+[目标类型键名称]

3种不同的外键名称命名之间存在优先级:

[目标类型的键名] > [引用属性名称]+[目标类型键名称] > [目标类型名称]+[目标类型键名称]。

1.[目标类型的键名]

  • 两个类中分别包含一个引用和一个集合属性的一对多种。
  • 启用级联删除功能。

2.[目标类型名称]+[目标类型键名称]

  • 两个类中一个类包含另一个类的集合属性。

3.[引用属性名称]+[目标类型键名称]

2.一对多关系

修改外键命名约定,自定义外键列名

Data Annotations方式

  1. public int CatID { get; set; } 

  2. [ForeignKey("CatID")] 

  3. public virtual Category Category { get; set; } 

  4. //或者 

  5. [ForeignKey("Category")] 

  6. public int CatID { get; set; } 

  7. public virtual Category Category { get; set; } 

Fluent API方式

  • 两个实体类之间的关系,可以两个类中均添加关系映射配置,也可以只对其中任意一个实体类添加关系映射配置。
  • 建议将实体类之间关系映射配置在包含外键的类中
  1. modelBuilder.Entity<Product>() 

  2. .HasRequired(t => t.Category) 

  3. .WithMany(t => t.Products) 

  4. .HasForeignKey(d => d.CatID); 

  • 一对多关系关系生成的外键引用约束默认是有级联删除的,可以通过以下方式禁用Category与Product之间的级联删除。
  1. protected override void OnModelCreating(DbModelBuilder modelBuilder) 



  2. modelBuilder.Entity<Product>() 

  3. .HasRequired(t => t.Category) 

  4. .WithMany(t => t.Products) 

  5. .HasForeignKey(d => d.CatID) 

  6. .WillCascadeOnDelete(false); 



  7. //也可以在Entity Framework Code First生成的全部表中都统一设置禁用一对多级联删除。 

  8. protected override void OnModelCreating(DbModelBuilder modelBuilder) 



  9. modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 



  • 可以支持外键列名自定义的,但在实际的项目中,更多的外键列名称还是与所引用表的主键列名相同。

3.一对一关系

  • 两个表均有各自的主键,但要看哪个表的主键同时作为外键引用另一个表的主键。

Data Annotations方式

UserProfile表中的主键ProfileID同时也作为外键引用User表中的主键UserID。

User为主表

  1. public partial class User 



  2. [Key] 

  3. public int UserID { get; set; } 

  4. public string UserName { get; set; } 

  5. public string Password { get; set; } 

  6. public Nullable<bool> IsValid { get; set; } 


  7. public virtual UserProfile UserProfile { get; set; } 




  8. ------------------------------------------------------------------------------------------ 

  9. public partial class UserProfile 



  10. [Key] 

  11. [ForeignKey("User")] 

  12. public int ProfileID { get; set; } 

  13. public string Name { get; set; } 

  14. public Nullable<bool> Sex { get; set; } 

  15. public Nullable<DateTime> Birthday { get; set; } 

  16. public string Email { get; set; } 

  17. public string Telephone { get; set; } 

  18. public string Mobilephone { get; set; } 

  19. public string Address { get; set; } 

  20. public Nullable<DateTime> CreateDate { get; set; } 


  21. public virtual User User { get; set; } 



表User主键UserID将同时作为外键引用UserProfile表的主键ProfileID。

UserProfile为主表

  1. public partial class User 



  2. [Key] 

  3. [ForeignKey("UserProfile")] 

  4. public int UserID { get; set; } 

  5. public string UserName { get; set; } 

  6. public string Password { get; set; } 

  7. public Nullable<bool> IsValid { get; set; } 


  8. public virtual UserProfile UserProfile { get; set; } 




  9. ------------------------------------------------------------------------------------------ 

  10. public partial class UserProfile 



  11. [Key] 

  12. public int ProfileID { get; set; } 

  13. public string Name { get; set; } 

  14. public Nullable<bool> Sex { get; set; } 

  15. public Nullable<DateTime> Birthday { get; set; } 

  16. public string Email { get; set; } 

  17. public string Telephone { get; set; } 

  18. public string Mobilephone { get; set; } 

  19. public string Address { get; set; } 

  20. public Nullable<DateTime> CreateDate { get; set; } 


  21. public virtual User User { get; set; } 



Fluent API方式

UserProfile表中的主键ProfileID同时也作为外键引用User表中的主键UserID。

User为主表

  1. public partial class User 



  2. public int UserID { get; set; } 

  3. public string UserName { get; set; } 

  4. public string Password { get; set; } 

  5. public Nullable<bool> IsValid { get; set; } 


  6. public virtual UserProfile UserProfile { get; set; } 



  7. ------------------------------------------------------------------------------------------ 

  8. public class UserMap : EntityTypeConfiguration<User> 



  9. public UserMap() 



  10. // Primary Key 

  11. this.HasKey(t => t.UserID); 


  12. // Properties 

  13. this.Property(t => t.UserName) 

  14. .HasMaxLength(50); 


  15. this.Property(t => t.Password) 

  16. .HasMaxLength(100); 


  17. // Table & Column Mappings 

  18. this.ToTable("User"); 

  19. this.Property(t => t.UserID).HasColumnName("UserID"); 

  20. this.Property(t => t.UserName).HasColumnName("UserName"); 

  21. this.Property(t => t.Password).HasColumnName("Password"); 

  22. this.Property(t => t.IsValid).HasColumnName("IsValid"); 





  23. ------------------------------------------------------------------------------------------  

  24. public partial class UserProfile 



  25. public int UserID { get; set; } 

  26. public string Name { get; set; } 

  27. public Nullable<bool> Sex { get; set; } 

  28. public Nullable<DateTime> Birthday { get; set; } 

  29. public string Email { get; set; } 

  30. public string Telephone { get; set; } 

  31. public string Mobilephone { get; set; } 

  32. public string Address { get; set; } 

  33. public Nullable<DateTime> CreateDate { get; set; } 


  34. public virtual User User { get; set; } 



  35. ------------------------------------------------------------------------------------------  

  36. public class UserProfileMap : EntityTypeConfiguration<UserProfile> 



  37. public UserProfileMap() 



  38. // Primary Key 

  39. this.HasKey(t => t.UserID); 


  40. // Properties 

  41. this.Property(t => t.UserID) 

  42. .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 


  43. this.Property(t => t.Name) 

  44. .IsRequired() 

  45. .HasMaxLength(50); 


  46. this.Property(t => t.Email) 

  47. .IsRequired() 

  48. .HasMaxLength(100); 


  49. this.Property(t => t.Telephone) 

  50. .HasMaxLength(50); 


  51. this.Property(t => t.Mobilephone) 

  52. .HasMaxLength(20); 


  53. this.Property(t => t.Address) 

  54. .HasMaxLength(200); 


  55. // Table & Column Mappings 

  56. this.ToTable("UserProfile"); 

  57. this.Property(t => t.UserID).HasColumnName("UserID"); 

  58. this.Property(t => t.Name).HasColumnName("Name"); 

  59. this.Property(t => t.Sex).HasColumnName("Sex"); 

  60. this.Property(t => t.Birthday).HasColumnName("Birthday"); 

  61. this.Property(t => t.Email).HasColumnName("Email"); 

  62. this.Property(t => t.Telephone).HasColumnName("Telephone"); 

  63. this.Property(t => t.Mobilephone).HasColumnName("Mobilephone"); 

  64. this.Property(t => t.Address).HasColumnName("Address"); 

  65. this.Property(t => t.CreateDate).HasColumnName("CreateDate"); 


  66. // Relationships 

  67. this.HasRequired(t => t.User) 

  68. .WithRequiredDependent(t => t.UserProfile); 





表User主键UserID将同时作为外键引用UserProfile表的主键ProfileID。

UserProfile为主表

  1. public class UserProfileMap : EntityTypeConfiguration<UserProfile> 



  2. public UserProfileMap() 



  3. // Primary Key 

  4. this.HasKey(t => t.UserID); 


  5. // Properties 

  6. this.Property(t => t.UserID) 

  7. .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 


  8. this.Property(t => t.Name) 

  9. .IsRequired() 

  10. .HasMaxLength(50); 


  11. this.Property(t => t.Email) 

  12. .IsRequired() 

  13. .HasMaxLength(100); 


  14. this.Property(t => t.Telephone) 

  15. .HasMaxLength(50); 


  16. this.Property(t => t.Mobilephone) 

  17. .HasMaxLength(20); 


  18. this.Property(t => t.Address) 

  19. .HasMaxLength(200); 


  20. // Table & Column Mappings 

  21. this.ToTable("UserProfile"); 

  22. this.Property(t => t.UserID).HasColumnName("UserID"); 

  23. this.Property(t => t.Name).HasColumnName("Name"); 

  24. this.Property(t => t.Sex).HasColumnName("Sex"); 

  25. this.Property(t => t.Birthday).HasColumnName("Birthday"); 

  26. this.Property(t => t.Email).HasColumnName("Email"); 

  27. this.Property(t => t.Telephone).HasColumnName("Telephone"); 

  28. this.Property(t => t.Mobilephone).HasColumnName("Mobilephone"); 

  29. this.Property(t => t.Address).HasColumnName("Address"); 

  30. this.Property(t => t.CreateDate).HasColumnName("CreateDate"); 


  31. // Relationships 

  32. this.HasRequired(t => t.User) 

  33. .WithRequiredPrincipal(t => t.UserProfile); 





4.多对多关系

  • 除了生成实体类定义的属性表之外,还会生成一个中间表。用于体现两个实体表之间的多对多的关系。
  1. public partial class User 



  2. public int UserID { get; set; } 

  3. public string UserName { get; set; } 

  4. public string Password { get; set; } 

  5. public Nullable<bool> IsValid { get; set; } 


  6. public virtual ICollection<Role> Roles { get; set; } 




  7. public partial class Role 



  8. public Role() 



  9. this.Users = new List<User>(); 




  10. public int RoleID { get; set; } 

  11. public string RoleName { get; set; } 


  12. public virtual ICollection<User> Users { get; set; } 



  • 默认启用多对多的数据级联删除

  1. protected override void OnModelCreating(DbModelBuilder modelBuilder) 



  2. // 禁用多对多关系表的级联删除 

  3. modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>(); 




Fluent API方式

  1. public partial class User 



  2. public int UserID { get; set; } 

  3. public string UserName { get; set; } 

  4. public string Password { get; set; } 

  5. public Nullable<bool> IsValid { get; set; } 


  6. public virtual ICollection<Role> Roles { get; set; } 



  7. --------------------------------------------------------------------- 

  8. public class UserMap : EntityTypeConfiguration<User> 



  9. public UserMap() 



  10. // Primary Key 

  11. this.HasKey(t => t.UserID); 


  12. // Properties 

  13. this.Property(t => t.UserName) 

  14. .HasMaxLength(50); 


  15. this.Property(t => t.Password) 

  16. .HasMaxLength(100); 


  17. // Table & Column Mappings 

  18. this.ToTable("User"); 

  19. this.Property(t => t.UserID).HasColumnName("UserID"); 

  20. this.Property(t => t.UserName).HasColumnName("UserName"); 

  21. this.Property(t => t.Password).HasColumnName("Password"); 

  22. this.Property(t => t.IsValid).HasColumnName("IsValid"); 





  23. ---------------------------------------------------------------------------- 

  24. public partial class Role 



  25. public int RoleID { get; set; } 

  26. public string RoleName { get; set; } 


  27. public virtual ICollection<User> Users { get; set; } 



  28. ----------------------------------------------------------------------------- 

  29. public class RoleMap : EntityTypeConfiguration<Role> 



  30. public RoleMap() 



  31. // Primary Key 

  32. this.HasKey(t => t.RoleID); 


  33. // Properties 

  34. this.Property(t => t.RoleName) 

  35. .HasMaxLength(50); 


  36. // Table & Column Mappings 

  37. this.ToTable("Role"); 

  38. this.Property(t => t.RoleID).HasColumnName("RoleID"); 

  39. this.Property(t => t.RoleName).HasColumnName("RoleName"); 


  40. // Relationships 

  41. this.HasMany(t => t.Users) 

  42. .WithMany(t => t.Roles) 

  43. .Map(m => 



  44. m.ToTable("UserRole"); 

  45. m.MapLeftKey("RoleID"); 

  46. m.MapRightKey("UserID"); 

  47. }); 






5.一对多自反关系

Fluent API方式

  1. public class Category 



  2. public int CategoryID { get; set; } 

  3. public int CategoryNo { get; set; } 

  4. public string CategoryName { get; set; } 

  5. public Nullable<int> ParentID { get; set; } 

  6. public virtual Category Parent { get; set; } 

  7. public virtual ICollection<Category> Children { get; set; } 



  8. --------------------------------------------------------------------- 

  9. public class CategoryMap : EntityTypeConfiguration<Category> 



  10. public CategoryMap() 



  11. // Primary Key 

  12. this.HasKey(t => t.CategoryID); 


  13. // Properties 

  14. this.Property(t => t.CategoryName) 

  15. .IsRequired() 

  16. .HasMaxLength(50); 


  17. // Table & Column Mappings 

  18. this.ToTable("Category"); 

  19. this.Property(t => t.CategoryID).HasColumnName("CategoryID"); 

  20. this.Property(t => t.CategoryNo).HasColumnName("CategoryNo"); 

  21. this.Property(t => t.CategoryName).HasColumnName("CategoryName"); 

  22. this.Property(t => t.ParentID).HasColumnName("ParentID"); 


  23. // Relationships 

  24. this.HasOptional(t => t.Parent) 

  25. .WithMany(t => t.Children) 

  26. .HasForeignKey(d => d.ParentID); 





6.多对多自反关系

Fluent API方式

  1. /// <summary> 

  2. /// Family表多对多自反关系 

  3. /// </summary> 

  4. public partial class Family 



  5. public Family() 



  6. this.Parents = new List<Family>(); 

  7. this.Children = new List<Family>(); 




  8. public int FamilyID { get; set; } 

  9. public string Name { get; set; } 

  10. public Nullable<bool> Sex { get; set; } 

  11. public Nullable<System.DateTime> Birthday { get; set; } 

  12. public virtual ICollection<Family> Parents { get; set; } 

  13. public virtual ICollection<Family> Children { get; set; } 



  14. --------------------------------------------------------------------- 

  15. public class FamilyMap : EntityTypeConfiguration<Family> 



  16. public FamilyMap() 



  17. // Primary Key 

  18. this.HasKey(t => t.FamilyID); 


  19. // Properties 

  20. this.Property(t => t.Name) 

  21. .HasMaxLength(50); 


  22. // Table & Column Mappings 

  23. this.ToTable("Family"); 

  24. this.Property(t => t.FamilyID).HasColumnName("FamilyID"); 

  25. this.Property(t => t.Name).HasColumnName("Name"); 

  26. this.Property(t => t.Sex).HasColumnName("Sex"); 

  27. this.Property(t => t.Birthday).HasColumnName("Birthday"); 


  28. // Relationships 

  29. this.HasMany(t => t.Parents) 

  30. .WithMany(t => t.Children) 

  31. .Map(m => 



  32. m.ToTable("FamilyRelationship"); 

  33. m.MapLeftKey("ParentID"); 

  34. m.MapRightKey("ChildID"); 

  35. }); 





EFCodeFirst关系映射约定的更多相关文章

  1. EFCodeFirst属性映射约定

    EFCodeFirst属性映射约定 EFCodeFirst 属性映射约定 CodeFirst与数据表之间得映射方式又两种:Data Annotation和Fluent API 默认约定: 表名为类名的 ...

  2. Entity Framework Code First关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  3. Entity Framework Code First主外键关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  4. Entity Framework Code First关系映射约定【l转发】

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  5. Entity Framework Code First属性映射约定

    Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API.本文中采用创建Product类为例来说明tity Fram ...

  6. EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public?

    前言 不知我们是否思考过一个问题,在关系映射中对于导航属性的访问修饰符是否一定必须为public呢?如果从未想过这个问题,那么我们接下来来探讨这个问题. EF 6.x和EF Core 何种情况下必须配 ...

  7. 【EF】Entity Framework实现属性映射约定

    Entity Framework Code First属性映射约定中“约定”一词,在原文版中为“Convention”,翻译成约定或许有些不好理解,这也是网上比较大多数的翻译,我们就当这是Entity ...

  8. 补习知识:Entity Framework Code First属性映射约定

    Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API.本文中采用创建Product类为例来说明tity Fram ...

  9. 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制

    你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...

随机推荐

  1. VS CODE一些常见配置操作(快捷键设置、C/C++的debug、代码路径配置)

    总述     今天来一篇简单的操作文章吧,VSCODE是我们经常用的软件,我之前也写过关于VSCODE远程办公的一些的操作(有兴趣的朋友可以点击进去看看),今天我再稍微介绍一些我其他地方用到的一些操作 ...

  2. P2762 太空飞行计划问题 (最小割)

    题意:n个实验 每个实验可获利ai元 做每个实验需要几个仪器 购买每个仪器有不同的花费 不同实验可能会用到同一个仪器 只用购买一次 求最大收益 题解:......................... ...

  3. 【hdu 1573】X问题(数论--拓展欧几里德 求解同余方程组的个数)

    题目:求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], -, X mod a[i] = b[i] ...

  4. Color Changing Sofa Gym - 101962B、Renan and Cirque du Soleil Gym - 101962C、Hat-Xor Gym - 101962E 、Rei do Cangaço Gym - 101962K 、Sorting Machine Gym - 101962M

    Color Changing Sofa Gym - 101962B 题意:给你一个由字母构成的字符串a,再给你一个由0.1构成的字符串b.你需要在a字符串中找到一个可以放下b的位置,要保证b字符串中0 ...

  5. zoj3623 Battle Ships

    Battle Ships is a new game which is similar to Star Craft. In this game, the enemy builds a defense ...

  6. AtCoder Beginner Contest 173 E - Multiplication 4 (思维)

    题意:有\(n\)个数,从中选\(k\)个数累乘,求最大的乘积\((mod\ 10^9+7)\). 题解: 1.假如全是负数,并且选奇数个,那么从小到大选. 2.否则,考虑当前状态,假如\(k\)是奇 ...

  7. 一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(一)

    JavaScript 设计模式(一) 本文需要读者至少拥有基础的 ES6 知识,包括 Proxy, Reflect 以及 Generator 函数等. 至于这次为什么分了两篇文章,有损传统以及标题的正 ...

  8. 快速获取 Wi-Fi 密码——GitHub 热点速览 v.21.06

    作者:HelloGitHub-小鱼干 还有 2 天开启春节七天宅家生活,GitHub 也凑了一把春节热闹,wifi-password 连续霸榜 3 天,作为一个能快速让你连上 Wi-Fi 的小工具,春 ...

  9. leetcode 22. 括号生成 dfs

    先思考符合要求的串是什么样子的 任意时刻,(数量大于),且最后(==)==n即可 考虑下一个加入string的字符时(或者)即可 dfs class Solution { public: vector ...

  10. bnuoj-53073 萌萌哒身高差 【数学】【非原创】

    "清明时节雨纷纷,路上行人欲断魂." 然而wfy同学的心情是愉快的,因为BNU ACM队出去春游啦!并且,嗯... 以下是wfy同学的日记: 昨天,何老师告诉我们:明天我们去春游, ...