Web开发:ORM框架之使用Freesql的导航属性

news/2025/2/27 9:13:30

一、什么时候用导航属性

        看数据库表的对应关系,一对多的时候用比较好,不用多写一个联表实体,而且查询高效

 二、为实体配置导航属性

1.给关系是一的父表实体加上:

    [FreeSql.DataAnnotations.Navigate(nameof(子表.子表关联字段))]
    public List<子表> xxx { get; set; } = new List<子表>();

2.给关系是n的子表实体加上:

    [FreeSql.DataAnnotations.Navigate(nameof(子表关联字段))]
    public 父表 yyy { get; set; }

3.Demo例子:(一个省份对应多个城市)

/// <summary>
/// 1
/// </summary>
[Table("Province")]
public class Province
{

    [FreeSql.DataAnnotations.Column(IsPrimary = true, IsIdentity = true, Name = "Id")]
    public int Id { get; set; }

    [Column("ProvinceCode")]
    public int? ProvinceCode { get; set; }

    [FreeSql.DataAnnotations.Navigate(nameof(City.ProvinceId))]
    public List<City> citys { get; set; } = new List<City>();
}

/// <summary>
/// n
/// </summary>
[Table("City")]
public class City
{

    [FreeSql.DataAnnotations.Column(IsPrimary = true, IsIdentity = true, Name = "Id")]
    public int Id { get; set; }

    [Column("CityCode")]
    public int? CityCode { get; set; }

    [Column("ProvinceId")]
    public int ProvinceId { get; set; }

    [Column("CityGroup")]
    public int? CityGroup { get; set; }

    [FreeSql.DataAnnotations.Navigate(nameof(ProvinceId))]
    public Province province { get; set; }
}

 三、怎么用导航属性

原理:左外连接

总结:使用关键字Include(找父表)、IncludeMany(找子表)

// 一对多导航属性关联查询
// 01 无条件查询
// 导航属性带出其父表(可序列化)
var list1 = MSfsql.Select<City>().Include(x => x.province).ToList();

// 导航属性带出其子表(不可序列化,因为子表含有父表字段,会一直引用下去)
var list2 = MSfsql.Select<Province>().IncludeMany(x => x.citys).ToList();

// 02 有条件查询
// 【子表 -> 父表】
var query1 = MSfsql.Select<City>().Where(x => (x.province.Id < 20) && (x.Id == 1 || x.Id == 198)) //先对本表(子表)筛选,条件可含子表 父表
                                    .Include(x=>x.province) // 选择带出查询结果对应的那个父表
                                    .ToList();

// 【父表->子表】
var query2 = MSfsql.Select<Province>()
                    .Where(x => x.Id < 20 && x.citys.Any(x=> x.Id ==1 || x.Id==198 )) //先对本表(父表)筛选,条件可含子表 父表
                    .IncludeMany(x => x.citys) // 选择带出查询结果对应的多个子表
                    .ToList();

var query3 = MSfsql.Select<Province>()
                    .Where(x => x.Id < 20 && x.citys.Any(x => x.Id == 1 || x.Id == 198)) //先对本表(父表)筛选,条件可含子表 父表
                    .IncludeMany(x => x.citys, then => then.Where(x=> x.CityGroup == 1)) // 选择带出子表,并且要求子表具备一定条件
                    .ToList();

四、一对多免导航属性配置的写法

1.实体

        仅给关系是一的父表实体加上List<子表>字段即可

/// <summary>
/// 1
/// </summary>
[Table("Province")]
public class Province
{
 
    [FreeSql.DataAnnotations.Column(IsPrimary = true, IsIdentity = true, Name = "Id")]
    public int Id { get; set; }
 
    [Column("ProvinceCode")]
    public int? ProvinceCode { get; set; }
 
    //[FreeSql.DataAnnotations.Navigate(nameof(City.ProvinceId))]
    public List<City> citys { get; set; } = new List<City>();
}
 
/// <summary>
/// n
/// </summary>
[Table("City")]
public class City
{
 
    [FreeSql.DataAnnotations.Column(IsPrimary = true, IsIdentity = true, Name = "Id")]
    public int Id { get; set; }
 
    [Column("CityCode")]
    public int? CityCode { get; set; }
 
    [Column("ProvinceId")]
    public int ProvinceId { get; set; }
 
    [Column("CityGroup")]
    public int? CityGroup { get; set; }
 
    // [FreeSql.DataAnnotations.Navigate(nameof(ProvinceId))]
    // public Province province { get; set; }
}

2.查询方法

原理:先查满足条件的父表,提取出这些父表ID,再通过提取的父表ID查子表,freesql内部代码会通过IncludeMany里面的表达式树关联父表和子表

var query4 = fsql.Select<Province>()
                .Where(x=>x.Id > 10) //此处写父表 or 子表的查询条件,筛选出父表
                .IncludeMany(x => x.citys.Where(y => x.Id == y.ProvinceId)) //此处写关联条件,带出子表
                .ToList();//本质是查两次,freesql内部有代码优化机制


http://www.niftyadmin.cn/n/5869857.html

相关文章

鸿蒙5.0实战案例:基于RichEditor的评论编辑

往期推文全新看点&#xff08;文中附带全新鸿蒙5.0全栈学习笔录&#xff09; ✏️ 鸿蒙&#xff08;HarmonyOS&#xff09;北向开发知识点记录~ ✏️ 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ ✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景&#…

C++ 二叉搜索树与双向链表_牛客题霸_牛客网

点击链接即可查看题目: 二叉搜索树与双向链表_牛客题霸_牛客网 一、题目 描述 输入一棵二叉搜索树&#xff0c;将该二叉搜索树转换成一个排序的双向链表。如下图所示 数据范围&#xff1a;输入二叉树的节点数 0≤n≤10000≤n≤1000&#xff0c;二叉树中每个节点的值 0≤val≤10…

Go中slice和map引用传递误区

背景 关于slice和map是指传递还是引用传递&#xff0c;很多文章都分析得模棱两可&#xff0c;其实在Go中只有值传递&#xff0c;但是很多情况下是因为分不清slice和map的底层实现&#xff0c;所以导致很多人在这一块产生疑惑&#xff0c;下面通过代码案例分析slice和map到底是…

【Linux】调试工具GDB的使用及案例讲解

Linux系列 文章目录 Linux系列前言一、gdb的使用背景二、gdb的使用总结 本篇主要针对小白讲解&#xff0c;可以很多地方比较咯嗦 前言 GDB是Linux下一款强大的调试工具。GDB可以调试C、C、Java等语言&#xff0c;对于在Linux下工作的程序员来说&#xff0c;GDB是必不可少的调试…

数据存储:一文掌握存储数据到MongoDB详解

文章目录 一、环境准备1.1 安装MongoDB1.2 安装Python MongoDB驱动 二、连接到MongoDB2.1 基本连接2.2 连接到MongoDB Atlas&#xff08;云服务&#xff09; 三、基本CRUD操作3.1 创建&#xff08;Create&#xff09;&#xff1a;插入数据3.2 读取&#xff08;Read&#xff09;…

【学习方法】学习软件专业课程的思考方式

学习软件专业课程的思考方式 在学习软件专业课程时&#xff0c;我们往往会遇到一些看似简单但实际上却非常复杂的概念和理论。这种时候&#xff0c;我们可能会觉得书本很厚&#xff0c;难以理解。然而&#xff0c;这种看似简单的想法并不一定就是错误的&#xff0c;因为它激发…

去中心化技术P2P框架

中心化网络与去中心化网络 1. 中心化网络 在传统的中心化网络中&#xff0c;所有客户端都通过一个中心服务器进行通信。这种网络拓扑结构通常是一个星型结构&#xff0c;其中服务器作为中心节点&#xff0c;每个客户端只能与服务器通信。如果客户端之间需要通信&#xff0c;必须…

ElasticSearch 是如何实现分布式的?

ElasticSearch 是如何实现分布式的&#xff1f; 如果你正在准备技术面试&#xff0c;或者想深入理解 ElasticSearch&#xff08;简称 ES&#xff09;是如何实现分布式的&#xff0c;这篇文章将用通俗易懂的方式来讲解。 1. 为什么需要分布式搜索&#xff1f; 在互联网行业&a…