Skip to content

实体关系

2881099 edited this page Sep 4, 2023 · 34 revisions

中文 | English

FreeSql 提供 OneToMany, ManyToOne, ManyToMany, OneToOne, Parent, PgArrayToMany 六种导航属性关系。

导航属性能干什么?

导航属性进行多表查询非常方便,lambda 表达式中直接使用导航对象点点点,舒服!!

自定义配置

OneToMany/ManyToMany 支持的类型:ICollection<T>、List<T>、ObservableCollection<T>

//OneToMany class Group { [Navigate(nameof(User.GroupId))] public List<User> Users { get; set; } //在 User 查找 GroupId 属性,与 本实体.主键 关联 } //ManyToOne class User { public int GroupId { get; set; } [Navigate(nameof(GroupId))] public Group Group { get; set; } //在 本实体 查找 GroupId 属性,与 Group.主键 关联 } //ManyToMany [Navigate(ManyToMany = typeof(TagSong))] public List<Tag> Items { get; set; }

也可以使用 FluentApi 在外部设置导航关系:

fsql.CodeFirst.ConfigEntity<T>(a => a .Navigate(b => b.roles, null, typeof(TMid)) .Navigate(b => b.users, "uid") );

注意:

1、属性设置 Column(IsIgnore = true) 后,导航属性会失效

2、Navigate 设置的字符串是 类属性名,不是表 字段名!!!

预热说明:导航属性配置的加载,因为要解决死循环引用,当相互引用关系很复杂的时候,可能导致首次使用导航属性失败,第二次就可以了。解决办法可以程序启动时就预热所有实体类,循环执行 fsql.Select<object>().AsType(实体类);

与非主键关联

//OneToMany [Navigate(nameof(User.GroupId), TempPrimary = nameof(Code))] public List<User> Users { get; set; } //ManyToOne [Navigate(nameof(GroupId), TempPrimary = nameof(Group.Code))] public Group Group { get; set; }

非主键关联权支持 OneToMany/ManyToOne 两种关系,并且只能在查询的时候有效。(不支持级联保存、级联删除)

检测导航属性

如何检测一个导航属性是否有效:

var tbref = fsql.CodeFirst .GetTableByEntity(typeof(T)) .GetTableRef("Children", true);

GetTableRef(string propertyName, bool isThrow);

OneToOne

class User { [Key] public int Id { get; set; } [Navigate(nameof(Id))] public UserExt Ext { get; set; } //... } class UserExt { [Key] public int UserId { get; set; } [Navigate(nameof(UserId))] public User User { get; set; } //... }

一对一,要求两边都使用 Navigate 特性与自身的【主键】关联。(支持级联保存,级联删除)

PgArrayToMany

class User { public int[] RoleIds { get; set; } [Navigate(nameof(RoleIds))] public List<Role> Roles { get; set; } } class Role { public int Id { get; set; } [Navigate(nameof(User.RoleIds))] public List<User> Users { get; set; } }

更多资料:#1145

约定命名(无须指明 Navigate)

提示:本节内容稍微了解即可,不是必须掌握的,可以跳过。

class Group { public int Id { get; set; } //Id、GroupId、Group_id public List<User> AUsers { get; set; } public List<User> BUsers { get; set; } public int ParentId { get; set; } //ParentId、Parent_id public Group Parent { get; set; } public List<Group> Childs { get; set; } } class User { public int Id { get; set; } //Id、UserId、User_id public UserExt Ext { get; set; } public int AGroupId { get; set; } public Group AGroup { get; set; } public int BGroupId { get; set; } public Group BGroup { get; set; } public List<Role> Roles { get; set; } } class UserExt { public int UserId { get; set; } public User User { get; set; } } class Role { public int Id { get; set; } public string Name { get; set; } public List<User> Users { get; set; } } class UserRole { public int UserId { get; set; } public User User { get; set; } public int RoleId { get; set; } public Role Role { get; set; } }
Clone this wiki locally