FreeSql取多表数据
该篇内容由个人博客点击跳转同步更新!转载请注明出处!
以文章随笔与分类为例。
- 表结构
部分字段如下,其他省略,为了展示一对多关联,一个分类下可以有多个文章。一个文章属于一个分类。
blog_article (随笔表)
字段 | 类型 | 备注 |
---|---|---|
id | int | |
classify_id | int | 分类id |
title | varchar(50) | 标题 |
content | varchar(4000) | 正文 |
blog_classify (随笔分类专栏)
字段 | 类型 | 备注 |
---|---|---|
id | int | |
ClassifyName | varchar(50) | 分类名 |
其中FullAduitEntity,Entity,在开源项目中,可以自行搜索,其中就是ABP中的创建时间、是否删除等字段
Article.cs
[Table(Name = "blog_article")]
public class Article : FullAduitEntity
{
/// <summary>
/// 文章所在分类专栏Id
/// </summary>
public int? ClassifyId { get; set; }
public Classify Classify { get; set; }
/// <summary>
/// 标题
/// </summary>
[Column(DbType = "varchar(200)")]
public string Title { get; set; }
/// <summary>
/// 正文
/// </summary>
[Column(DbType = "text")]
public string Content { get; set; }
}
Classify.cs
[Table(Name = "blog_classify")]
public class Classify:FullAduitEntity
{
public string ClassifyName { get; set; }
public List<Article> Articles { get; set; }
}
使用现有的导航属性
- 属性Classify为null
List<Article> articles1 = _articleRepository
.Select
.ToList();
2.属性Classify会有值
我们在前台取数据,也可以直接循环取Classify中的属性
List<Article>articles2= _articleRepository
.Select
.Include(r => r.Classify)
.ToList();
假如,后台有一些字段要想过滤掉,可使用AutoMapper,传给前台使用Dto,过滤创建时间,修改时间等审核日志
创建 ArticleDto
public class ArticleDto : Entity
{
/// <summary>
/// 类别Id
/// </summary>
public int? ClassifyId { get; set; }
/// <summary>
/// 类别名称
/// </summary>
public string ClassifyName { get; set; }
public string Content { get; set; }
public string Title { get; set; }
}
3、配合IMapper,转换为ArticleDto
List<ArticleDto> articles3 = _articleRepository
.Select
.ToList(r=>new
{
r.Classify,
Article=r
}).Select(r=>
{
ArticleDto articleDto=_mapper.Map<ArticleDto>(r.Article);
articleDto.ClassifyName = r.Classify.ClassifyName;
return articleDto;
}).ToList();
- 同样是使用IMapper转换,但这里Include进去了,用法稍微有点区别。
文档介绍Include"贪婪加载导航属性,如果查询中已经使用了 a.Parent.Parent 类似表达式,则可以无需此操作。。
这里说的查询使用了a.Parent.Parent,是指上面的3中,ToList 中的
.ToList(r=>new
{
r.Classify,
Article=r
})
r.Classify,会生成Join功能。如果不想ToList去选择需要的数据,可直接使用Include把需要关联的数据取出。在后面再使用Linq的Select把数据转换下,后面要注意r.Classify可能为null,需要?.取。因为ClassifyId非必填项。
List<ArticleDto> articles4 = _articleRepository
.Select
.Include(r => r.Classify)
.ToList().Select(r =>
{
ArticleDto articleDto = _mapper.Map<ArticleDto>(r);
articleDto.ClassifyName = r.Classify?.ClassifyName;
return articleDto;
}).ToList();
直接Join
- 不使用关联属性获取文章专栏,这时候类Article中的Classify属性和Classify表中的List<Article>可删除,
List<ArticleDto> articleDtos = _articleRepository
.Select
.From<Classify>((a, b) =>a.LeftJoin(r => r.ClassifyId == b.Id)
).ToList((s, a) => new
{
Article = s,
a.ClassifyName
})
.Select(r =>
{
ArticleDto articleDto = _mapper.Map<ArticleDto>(r.Article);
articleDto.ClassifyName = r.ClassifyName;
return articleDto;
}).ToList();
使用SQL直接获取文章及其分类名称
6.SQL需要自己增加is_deleted判断。
List<ArticleDto> t9 = _freeSql.Ado.Query<ArticleDto>($@"
SELECT a.*,b.item_name as classifyName
FROM blog_article a
LEFT JOIN base_item b
on a.classify_id=b.id where a.is_deleted=0"
);
总结
以上取出的数据行数都是一样的。
一对多。
- 写SQL,很简单。
- 使用ORM的Join,再配合Mapper就变得复杂了。
- 使用导航属性,取关联数据,一个InClude就解决问题了
- 使用导航属性,取关联数据,然后再配合Mapper,基本就要看你的Linq、AutoMapper的水平了。哈哈。
比如上面把Article类中的Classify中的某一个值取出转换成ArticleDto中的ClassifyName
作者: 、天上月OvO
出处:https://cnblogs.com/igeekfan
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端