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方式
- public int CatID { get; set; }
- [ForeignKey("CatID")]
- public virtual Category Category { get; set; }
- //或者
- [ForeignKey("Category")]
- public int CatID { get; set; }
- public virtual Category Category { get; set; }
Fluent API方式
- 两个实体类之间的关系,可以两个类中均添加关系映射配置,也可以只对其中任意一个实体类添加关系映射配置。
- 建议将实体类之间关系映射配置在包含外键的类中
- modelBuilder.Entity<Product>()
- .HasRequired(t => t.Category)
- .WithMany(t => t.Products)
- .HasForeignKey(d => d.CatID);
- 一对多关系关系生成的外键引用约束默认是有级联删除的,可以通过以下方式禁用Category与Product之间的级联删除。
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- modelBuilder.Entity<Product>()
- .HasRequired(t => t.Category)
- .WithMany(t => t.Products)
- .HasForeignKey(d => d.CatID)
- .WillCascadeOnDelete(false);
- }
- //也可以在Entity Framework Code First生成的全部表中都统一设置禁用一对多级联删除。
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
- }
- 可以支持外键列名自定义的,但在实际的项目中,更多的外键列名称还是与所引用表的主键列名相同。
3.一对一关系
- 两个表均有各自的主键,但要看哪个表的主键同时作为外键引用另一个表的主键。
Data Annotations方式
UserProfile表中的主键ProfileID同时也作为外键引用User表中的主键UserID。
User为主表
- public partial class User
- {
- [Key]
- public int UserID { get; set; }
- public string UserName { get; set; }
- public string Password { get; set; }
- public Nullable<bool> IsValid { get; set; }
- public virtual UserProfile UserProfile { get; set; }
- }
- ------------------------------------------------------------------------------------------
- public partial class UserProfile
- {
- [Key]
- [ForeignKey("User")]
- public int ProfileID { get; set; }
- public string Name { get; set; }
- public Nullable<bool> Sex { get; set; }
- public Nullable<DateTime> Birthday { get; set; }
- public string Email { get; set; }
- public string Telephone { get; set; }
- public string Mobilephone { get; set; }
- public string Address { get; set; }
- public Nullable<DateTime> CreateDate { get; set; }
- public virtual User User { get; set; }
- }
表User主键UserID将同时作为外键引用UserProfile表的主键ProfileID。
UserProfile为主表
- public partial class User
- {
- [Key]
- [ForeignKey("UserProfile")]
- public int UserID { get; set; }
- public string UserName { get; set; }
- public string Password { get; set; }
- public Nullable<bool> IsValid { get; set; }
- public virtual UserProfile UserProfile { get; set; }
- }
- ------------------------------------------------------------------------------------------
- public partial class UserProfile
- {
- [Key]
- public int ProfileID { get; set; }
- public string Name { get; set; }
- public Nullable<bool> Sex { get; set; }
- public Nullable<DateTime> Birthday { get; set; }
- public string Email { get; set; }
- public string Telephone { get; set; }
- public string Mobilephone { get; set; }
- public string Address { get; set; }
- public Nullable<DateTime> CreateDate { get; set; }
- public virtual User User { get; set; }
- }
Fluent API方式
UserProfile表中的主键ProfileID同时也作为外键引用User表中的主键UserID。
User为主表
- public partial class User
- {
- public int UserID { get; set; }
- public string UserName { get; set; }
- public string Password { get; set; }
- public Nullable<bool> IsValid { get; set; }
- public virtual UserProfile UserProfile { get; set; }
- }
- ------------------------------------------------------------------------------------------
- public class UserMap : EntityTypeConfiguration<User>
- {
- public UserMap()
- {
- // Primary Key
- this.HasKey(t => t.UserID);
- // Properties
- this.Property(t => t.UserName)
- .HasMaxLength(50);
- this.Property(t => t.Password)
- .HasMaxLength(100);
- // Table & Column Mappings
- this.ToTable("User");
- this.Property(t => t.UserID).HasColumnName("UserID");
- this.Property(t => t.UserName).HasColumnName("UserName");
- this.Property(t => t.Password).HasColumnName("Password");
- this.Property(t => t.IsValid).HasColumnName("IsValid");
- }
- }
- ------------------------------------------------------------------------------------------
- public partial class UserProfile
- {
- public int UserID { get; set; }
- public string Name { get; set; }
- public Nullable<bool> Sex { get; set; }
- public Nullable<DateTime> Birthday { get; set; }
- public string Email { get; set; }
- public string Telephone { get; set; }
- public string Mobilephone { get; set; }
- public string Address { get; set; }
- public Nullable<DateTime> CreateDate { get; set; }
- public virtual User User { get; set; }
- }
- ------------------------------------------------------------------------------------------
- public class UserProfileMap : EntityTypeConfiguration<UserProfile>
- {
- public UserProfileMap()
- {
- // Primary Key
- this.HasKey(t => t.UserID);
- // Properties
- this.Property(t => t.UserID)
- .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
- this.Property(t => t.Name)
- .IsRequired()
- .HasMaxLength(50);
- this.Property(t => t.Email)
- .IsRequired()
- .HasMaxLength(100);
- this.Property(t => t.Telephone)
- .HasMaxLength(50);
- this.Property(t => t.Mobilephone)
- .HasMaxLength(20);
- this.Property(t => t.Address)
- .HasMaxLength(200);
- // Table & Column Mappings
- this.ToTable("UserProfile");
- this.Property(t => t.UserID).HasColumnName("UserID");
- this.Property(t => t.Name).HasColumnName("Name");
- this.Property(t => t.Sex).HasColumnName("Sex");
- this.Property(t => t.Birthday).HasColumnName("Birthday");
- this.Property(t => t.Email).HasColumnName("Email");
- this.Property(t => t.Telephone).HasColumnName("Telephone");
- this.Property(t => t.Mobilephone).HasColumnName("Mobilephone");
- this.Property(t => t.Address).HasColumnName("Address");
- this.Property(t => t.CreateDate).HasColumnName("CreateDate");
- // Relationships
- this.HasRequired(t => t.User)
- .WithRequiredDependent(t => t.UserProfile);
- }
- }
表User主键UserID将同时作为外键引用UserProfile表的主键ProfileID。
UserProfile为主表
- public class UserProfileMap : EntityTypeConfiguration<UserProfile>
- {
- public UserProfileMap()
- {
- // Primary Key
- this.HasKey(t => t.UserID);
- // Properties
- this.Property(t => t.UserID)
- .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
- this.Property(t => t.Name)
- .IsRequired()
- .HasMaxLength(50);
- this.Property(t => t.Email)
- .IsRequired()
- .HasMaxLength(100);
- this.Property(t => t.Telephone)
- .HasMaxLength(50);
- this.Property(t => t.Mobilephone)
- .HasMaxLength(20);
- this.Property(t => t.Address)
- .HasMaxLength(200);
- // Table & Column Mappings
- this.ToTable("UserProfile");
- this.Property(t => t.UserID).HasColumnName("UserID");
- this.Property(t => t.Name).HasColumnName("Name");
- this.Property(t => t.Sex).HasColumnName("Sex");
- this.Property(t => t.Birthday).HasColumnName("Birthday");
- this.Property(t => t.Email).HasColumnName("Email");
- this.Property(t => t.Telephone).HasColumnName("Telephone");
- this.Property(t => t.Mobilephone).HasColumnName("Mobilephone");
- this.Property(t => t.Address).HasColumnName("Address");
- this.Property(t => t.CreateDate).HasColumnName("CreateDate");
- // Relationships
- this.HasRequired(t => t.User)
- .WithRequiredPrincipal(t => t.UserProfile);
- }
- }
4.多对多关系
- 除了生成实体类定义的属性表之外,还会生成一个中间表。用于体现两个实体表之间的多对多的关系。
- public partial class User
- {
- public int UserID { get; set; }
- public string UserName { get; set; }
- public string Password { get; set; }
- public Nullable<bool> IsValid { get; set; }
- public virtual ICollection<Role> Roles { get; set; }
- }
- public partial class Role
- {
- public Role()
- {
- this.Users = new List<User>();
- }
- public int RoleID { get; set; }
- public string RoleName { get; set; }
- public virtual ICollection<User> Users { get; set; }
- }
- 默认启用多对多的数据级联删除
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- // 禁用多对多关系表的级联删除
- modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
- }
Fluent API方式
- public partial class User
- {
- public int UserID { get; set; }
- public string UserName { get; set; }
- public string Password { get; set; }
- public Nullable<bool> IsValid { get; set; }
- public virtual ICollection<Role> Roles { get; set; }
- }
- ---------------------------------------------------------------------
- public class UserMap : EntityTypeConfiguration<User>
- {
- public UserMap()
- {
- // Primary Key
- this.HasKey(t => t.UserID);
- // Properties
- this.Property(t => t.UserName)
- .HasMaxLength(50);
- this.Property(t => t.Password)
- .HasMaxLength(100);
- // Table & Column Mappings
- this.ToTable("User");
- this.Property(t => t.UserID).HasColumnName("UserID");
- this.Property(t => t.UserName).HasColumnName("UserName");
- this.Property(t => t.Password).HasColumnName("Password");
- this.Property(t => t.IsValid).HasColumnName("IsValid");
- }
- }
- ----------------------------------------------------------------------------
- public partial class Role
- {
- public int RoleID { get; set; }
- public string RoleName { get; set; }
- public virtual ICollection<User> Users { get; set; }
- }
- -----------------------------------------------------------------------------
- public class RoleMap : EntityTypeConfiguration<Role>
- {
- public RoleMap()
- {
- // Primary Key
- this.HasKey(t => t.RoleID);
- // Properties
- this.Property(t => t.RoleName)
- .HasMaxLength(50);
- // Table & Column Mappings
- this.ToTable("Role");
- this.Property(t => t.RoleID).HasColumnName("RoleID");
- this.Property(t => t.RoleName).HasColumnName("RoleName");
- // Relationships
- this.HasMany(t => t.Users)
- .WithMany(t => t.Roles)
- .Map(m =>
- {
- m.ToTable("UserRole");
- m.MapLeftKey("RoleID");
- m.MapRightKey("UserID");
- });
- }
- }
5.一对多自反关系
Fluent API方式
- public class Category
- {
- public int CategoryID { get; set; }
- public int CategoryNo { get; set; }
- public string CategoryName { get; set; }
- public Nullable<int> ParentID { get; set; }
- public virtual Category Parent { get; set; }
- public virtual ICollection<Category> Children { get; set; }
- }
- ---------------------------------------------------------------------
- public class CategoryMap : EntityTypeConfiguration<Category>
- {
- public CategoryMap()
- {
- // Primary Key
- this.HasKey(t => t.CategoryID);
- // Properties
- this.Property(t => t.CategoryName)
- .IsRequired()
- .HasMaxLength(50);
- // Table & Column Mappings
- this.ToTable("Category");
- this.Property(t => t.CategoryID).HasColumnName("CategoryID");
- this.Property(t => t.CategoryNo).HasColumnName("CategoryNo");
- this.Property(t => t.CategoryName).HasColumnName("CategoryName");
- this.Property(t => t.ParentID).HasColumnName("ParentID");
- // Relationships
- this.HasOptional(t => t.Parent)
- .WithMany(t => t.Children)
- .HasForeignKey(d => d.ParentID);
- }
- }
6.多对多自反关系
Fluent API方式
- /// <summary>
- /// Family表多对多自反关系
- /// </summary>
- public partial class Family
- {
- public Family()
- {
- this.Parents = new List<Family>();
- this.Children = new List<Family>();
- }
- public int FamilyID { get; set; }
- public string Name { get; set; }
- public Nullable<bool> Sex { get; set; }
- public Nullable<System.DateTime> Birthday { get; set; }
- public virtual ICollection<Family> Parents { get; set; }
- public virtual ICollection<Family> Children { get; set; }
- }
- ---------------------------------------------------------------------
- public class FamilyMap : EntityTypeConfiguration<Family>
- {
- public FamilyMap()
- {
- // Primary Key
- this.HasKey(t => t.FamilyID);
- // Properties
- this.Property(t => t.Name)
- .HasMaxLength(50);
- // Table & Column Mappings
- this.ToTable("Family");
- this.Property(t => t.FamilyID).HasColumnName("FamilyID");
- this.Property(t => t.Name).HasColumnName("Name");
- this.Property(t => t.Sex).HasColumnName("Sex");
- this.Property(t => t.Birthday).HasColumnName("Birthday");
- // Relationships
- this.HasMany(t => t.Parents)
- .WithMany(t => t.Children)
- .Map(m =>
- {
- m.ToTable("FamilyRelationship");
- m.MapLeftKey("ParentID");
- m.MapRightKey("ChildID");
- });
- }
- }
EFCodeFirst关系映射约定的更多相关文章
- EFCodeFirst属性映射约定
EFCodeFirst属性映射约定 EFCodeFirst 属性映射约定 CodeFirst与数据表之间得映射方式又两种:Data Annotation和Fluent API 默认约定: 表名为类名的 ...
- Entity Framework Code First关系映射约定
本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...
- Entity Framework Code First主外键关系映射约定
本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...
- Entity Framework Code First关系映射约定【l转发】
本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...
- Entity Framework Code First属性映射约定
Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API.本文中采用创建Product类为例来说明tity Fram ...
- EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public?
前言 不知我们是否思考过一个问题,在关系映射中对于导航属性的访问修饰符是否一定必须为public呢?如果从未想过这个问题,那么我们接下来来探讨这个问题. EF 6.x和EF Core 何种情况下必须配 ...
- 【EF】Entity Framework实现属性映射约定
Entity Framework Code First属性映射约定中“约定”一词,在原文版中为“Convention”,翻译成约定或许有些不好理解,这也是网上比较大多数的翻译,我们就当这是Entity ...
- 补习知识:Entity Framework Code First属性映射约定
Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API.本文中采用创建Product类为例来说明tity Fram ...
- 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制
你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...
随机推荐
- 解析一下C++的异常处理
作者:良知犹存 转载授权以及围观:欢迎添加微信:Allen-Iverson-me-LYN 总述 在程序运行过程中经常会碰到一些问题,例如数组下标越界,除数为零等,这些错误不过能被发现处理, ...
- Equal Numbers Gym - 101612E 思维
题意: 给你n个数vi,你有k次操作.每一次操作你可以从n个数里面挑一个数,然后使得这个数乘于一个正整数.操作完之后,这n个数里面不同数的数量就是权值.你要使得这个值尽可能小. 题解: 如果a%b== ...
- UVA - 12295 最短路(迪杰斯特拉)——求按对称路线最短路条数
题意: 给你一个n,然后给你一个n*n的正方形w[i][j],你需要找到一个从(1,1)点走到(n,n)点的最短路径数量.而且这个路径必须按照y=x对称 题解: 我们把左上角的点当作(0,0)点,右下 ...
- Educational Codeforces Round 95 (Rated for Div. 2) A. Buying Torches (数学)
题意:刚开始你有一个木棍,造一个火炬需要一个木根和一个煤块,现在你可以用一个木棍换取\(x\)个木棍,或者\(y\)根木棍换一个煤块,消耗一次操作,问最少需要操作多少次才能造出\(k\)把火炬. 题解 ...
- Ubuntu上安装Python3编译器和 Pycharm 集成开发环境
一.安装python3 (Ubuntu上面是自带python编译器的,可以用命令"python -V"来查看版本号.我下面安装的是pyhton3编译器) 一条命令就可以 sudo ...
- forEachRemaining()方法的用法
forEachRemaining()是java1.8新增的Iterator接口中的默认方法对于这个方法,官方文档是这么描述的:Performs the given action for each re ...
- 牛客网-Beautiful Land 【01背包 + 思维】
链接:https://www.nowcoder.com/acm/contest/119/F来源:牛客网 Now HUST got a big land whose capacity is C to p ...
- Next.js SSR Tutorials
Next.js SSR Tutorials https://codesandbox.io/s/nextjs-demo-h49zt cli $ npx create-next-app ssr-demo- ...
- 2021 从零开始打造一个自己的 UI 组件库
2021 从零开始打造一个自己的 UI 组件库 refs GUI https://github.com/xgqfrms/gui/ https://www.npmjs.com/package/@xgqf ...
- CSS event pass through
CSS event pass through CSS 黑科技 / CSS 技巧: css 禁用点击事件, 实现事件冒泡的效果 https://caniuse.com/?search=CSS point ...