EFCore sharing

news/2024/5/19 23:06:58 标签: .netcore, 经验分享, 后端

前言

由于项目变动,最近接手了一个新的团队,发现代码常出现SQL性能问题,使用到EF Core技术,故针对常用的EF Core使用场景做了一些培训,同时也亲测这些代码。


一、Initiate tables

示例:主要使用到以下几个表,DB:PG。

var table1 = _dbContext.Sysusers;     //主表
var table2 = _dbContext.Sysuserroles; //从表
var table3 = _dbContext.Sysroles;     //从表

二、两表Join

1.Linq

2.Lambda

代码如下: 

#region 两表 join
        // a. Linq
        var query = from m in table1
                    join d in table2 on m.Userid equals d.Userid
                    select new { UserID = m.Userid, RoleID = d.Roleid };
        query.ToList();

        // b. Lambda
        query = table1.Join(table2, m => m.Userid, d => d.Userid, (m, d) => new { UserID = m.Userid, RoleID = d.Roleid });
        query.ToList();

 #endregion

生成SQL:

SELECT s.userid AS "UserID", s0.roleid AS "RoleID"
FROM sysuser AS s
INNER JOIN sysuserrole AS s0 ON s.userid = s0.userid

SELECT s.userid AS "UserID", s0.roleid AS "RoleID"
FROM sysuser AS s
INNER JOIN sysuserrole AS s0 ON s.userid = s0.userid 


 三、两表Left Join

1.Linq

2.Lambda

代码如下: 

#region 两表left join
        // a. Linq
        query = from m in table1
                join d in table2 on m.Userid equals d.Userid into jtemp
                from leftjoin in jtemp.DefaultIfEmpty()
                select new
                {
                    UserID = m.Userid,
                    RoleID = leftjoin.Roleid
                };
        query.ToList();

        // b. Lambda
        // GroupJoin:用于查询一对多的关系
        query = table1.GroupJoin(table2, a => a.Userid, b => b.Userid, (a, b) => new
        {
            userid = a.Userid,
            userrole = b
        }).SelectMany(a => a.userrole.DefaultIfEmpty(), (m, n) => new
        {
            UserID = m.userid,
            RoleID = n.Roleid
        });
        query.ToList();

        query = table1
            .SelectMany(a => table2.Where(b => b.Userid == a.Userid).DefaultIfEmpty(),
                        (m, n) => new { UserID = m.Userid, RoleID = n.Roleid });
        query.ToList();

#endregion

生成SQL:

SELECT s.userid AS "UserID", s0.roleid AS "RoleID"
FROM sysuser AS s
LEFT JOIN sysuserrole AS s0 ON s.userid = s0.userid

SELECT s.userid AS "UserID", s0.roleid AS "RoleID"
FROM sysuser AS s
LEFT JOIN sysuserrole AS s0 ON s.userid = s0.userid

SELECT s.userid AS "UserID", s0.roleid AS "RoleID"
FROM sysuser AS s
LEFT JOIN sysuserrole AS s0 ON s.userid = s0.userid 


 四、三表Join

1.Linq

2.Lambda

代码如下: 

#region 三表 join

        // a. Linq
        var query2 = from m in table1
                     join d in table2 on m.Userid equals d.Userid
                     join d2 in table3 on d.Roleid equals d2.Id
                     select new
                     {
                         UserID = m.Userid,
                         RoleID = d.Roleid,
                         RoleName = d2.Rolename
                     };
        query2.ToList();

        // b. Lambda
        query2 = table1.Join(table2, m => m.Userid, d => d.Userid, (m, d) => new
        {
            UserID = m.Userid,
            RoleID = d.Roleid
        }).Join(table3, m => m.RoleID, d => d.Id, (m, d) => new
        {
            UserID = m.UserID,
            RoleID = m.RoleID,
            RoleName = d.Rolename
        });
        query2.ToList();

#endregion

生成SQL:

SELECT s.userid AS "UserID", s0.roleid AS "RoleID", s1.rolename AS "RoleName"
FROM sysuser AS s
INNER JOIN sysuserrole AS s0 ON s.userid = s0.userid
INNER JOIN sysrole AS s1 ON s0.roleid = s1.id

SELECT s.userid AS "UserID", s0.roleid AS "RoleID", s1.rolename AS "RoleName"
FROM sysuser AS s
INNER JOIN sysuserrole AS s0 ON s.userid = s0.userid
INNER JOIN sysrole AS s1 ON s0.roleid = s1.id


 五、三表Left Join

1.Linq

2.Lambda

代码如下: 

#region 三表 left join
        // a. Linq
        query2 = from m in table1
                 join t1 in table2 on m.Userid equals t1.Userid into t1group
                 from d in t1group.DefaultIfEmpty()
                 join t2 in table3 on d.Roleid equals t2.Id into t2group
                 from d2 in t2group.DefaultIfEmpty()
                 select new
                 {
                     UserID = m.Userid,
                     RoleID = d.Roleid,
                     RoleName = d2.Rolename
                 };
        query2.ToList();

        // b. Lambda
        query2 = table1.GroupJoin(table2, a => a.Userid, b => b.Userid, (a, b) => new
        { userid = a.Userid, userrole = b }).SelectMany(a => a.userrole.DefaultIfEmpty(), (m, n) => new
        {
            userid = m.userid,
            roleid = n.Roleid
        }).GroupJoin(table3, a => a.roleid, b => b.Id, (m, n) => new
        {
            userid = m.userid,
            roleid = m.roleid,
            role = n
        }).SelectMany(a => a.role.DefaultIfEmpty(), (m, n) => new
        { UserID = m.userid, RoleID = m.roleid, RoleName = n.Rolename });
        query2.ToList();

        query2 = table1
            .SelectMany(a => table2.Where(b => b.Userid == a.Userid).DefaultIfEmpty(),
                        (m, n) => new { userid = m.Userid, roleid = n.Roleid })
            .SelectMany(a => table3.Where(b => b.Id == a.roleid).DefaultIfEmpty(),
                        (m, n) => new { UserID = m.userid, RoleID = m.roleid, RoleName = n.Rolename });
        query2.ToList();

#endregion

生成SQL:

SELECT s.userid AS "UserID", s0.roleid AS "RoleID", s1.rolename AS "RoleName"
FROM sysuser AS s
LEFT JOIN sysuserrole AS s0 ON s.userid = s0.userid
LEFT JOIN sysrole AS s1 ON s0.roleid = s1.id

SELECT s.userid AS "UserID", s0.roleid AS "RoleID", s1.rolename AS "RoleName"
FROM sysuser AS s
LEFT JOIN sysuserrole AS s0 ON s.userid = s0.userid
LEFT JOIN sysrole AS s1 ON s0.roleid = s1.id

SELECT s.userid AS "UserID", s0.roleid AS "RoleID", s1.rolename AS "RoleName"
FROM sysuser AS s
LEFT JOIN sysuserrole AS s0 ON s.userid = s0.userid
LEFT JOIN sysrole AS s1 ON s0.roleid = s1.id


 六、单表分组(include where)

1.Linq

2.Lambda

代码如下: 

#region 单表分组
        // a. Linq
        var queryGroup = from user in table1
                         group user by new { user.Userlang } into grouptemp
                         where grouptemp.Sum(a => a.Usertz) > 0
                         select new
                         {
                             grpby = grouptemp.Key,
                             sum = grouptemp.Sum(a => a.Usertz),
                             max = grouptemp.Max(a => a.Usertz),
                             min = grouptemp.Min(a => a.Usertz),
                             avg = grouptemp.Average(a => a.Usertz),
                             cnt = grouptemp.Count()
                         };
        queryGroup.ToList();

        // b. Lambda
        queryGroup = table1.GroupBy(a => new { a.Userlang }).Select(grouptemp => new
        {
            grpby = grouptemp.Key,
            sum = grouptemp.Sum(a => a.Usertz),
            max = grouptemp.Max(a => a.Usertz),
            min = grouptemp.Min(a => a.Usertz),
            avg = grouptemp.Average(a => a.Usertz),
            cnt = grouptemp.Count()
        }).Where(a => a.sum > 0);

        queryGroup.ToList();

#endregion

生成SQL:

SELECT s.userlang AS "Userlang", COALESCE(sum(s.usertz), 0.0) AS sum, max(s.usertz) AS max, min(s.usertz) AS min, avg(s.usertz) AS avg, count(*)::int AS cnt
FROM sysuser AS s
GROUP BY s.userlang
HAVING COALESCE(sum(s.usertz), 0.0) > 0.0

SELECT s.userlang AS "Userlang", COALESCE(sum(s.usertz), 0.0) AS sum, max(s.usertz) AS max, min(s.usertz) AS min, avg(s.usertz) AS avg, count(*)::int AS cnt
FROM sysuser AS s
GROUP BY s.userlang
HAVING COALESCE(sum(s.usertz), 0.0) > 0.0 


 七、WHERE IN

1.Linq

2.Lambda

代码如下: 

#region WHERE IN 
        // a. Linq
        var ids = new List<string> { "x", "xx", "xxx" }; // "x,xx,xxx".Split(',').ToList()
        var whereIn = from t in table1 where ids.Contains(t.Userid) select t;
        whereIn.ToList();

        // b. Lambda
        whereIn = table1.Where(t => ids.Contains(t.Userid));
        whereIn.ToList();

#endregion

生成SQL:

SELECT s.userid, s.cdate, s.cuser, s.mdate, s.muser, s.useravatar, s.userlang, s.usertz
FROM sysuser AS s
WHERE s.userid = ANY (@__ids_0)

SELECT s.userid, s.cdate, s.cuser, s.mdate, s.muser, s.useravatar, s.userlang, s.usertz
FROM sysuser AS s
WHERE s.userid = ANY (@__ids_0) 


 八、WHERE EXISTS

1.Linq

2.Lambda

代码如下: 

#region WHERE EXISTS
        // a. Linq
        var whereExists = from t1 in table1
                          where table2.Any(t2 => t2.Userid == t1.Userid && t2.Roleid == "1")
                          select t1;
        whereExists.ToList();

        // b. Lambda
        whereExists = table1.Where(t1 => table2.Any(t2 => t2.Userid == t1.Userid && t2.Roleid == "1"));
        whereExists.ToList();

#endregion

生成SQL:

SELECT s.userid, s.cdate, s.cuser, s.mdate, s.muser, s.useravatar, s.userlang, s.usertz
FROM sysuser AS s
WHERE EXISTS (
    SELECT 1
    FROM sysuserrole AS s0
    WHERE s0.userid = s.userid AND s0.roleid = '1')

SELECT s.userid, s.cdate, s.cuser, s.mdate, s.muser, s.useravatar, s.userlang, s.usertz
FROM sysuser AS s
WHERE EXISTS (
    SELECT 1
    FROM sysuserrole AS s0
    WHERE s0.userid = s.userid AND s0.roleid = '1') 


 九、WHERE LIKE

1.Linq

2.Lambda

代码如下: 

#region WHERE LIKE
        // a. Linq
        var whereLike = from p in table1
                        where p.Userid.Contains("Z") || p.Userlang.IndexOf("en") > 0 || p.Cuser.StartsWith("start") || p.Muser.EndsWith("end")
                        select p;
        whereLike.ToList();

        // b. Lambda
        whereLike = table1.Where(p => p.Userid.Contains("Z") || p.Userlang.IndexOf("en") > 0 || p.Cuser.StartsWith("start") || p.Muser.EndsWith("end"));
        whereLike.ToList();

#endregion

生成SQL:

SELECT s.userid, s.cdate, s.cuser, s.mdate, s.muser, s.useravatar, s.userlang, s.usertz
FROM sysuser AS s
WHERE strpos(s.userid, 'Z') > 0 OR (strpos(s.userlang, 'en') - 1) > 0 OR (s.cuser LIKE 'start%') OR ((s.muser IS NOT NULL) AND (s.muser LIKE '%end'))

SELECT s.userid, s.cdate, s.cuser, s.mdate, s.muser, s.useravatar, s.userlang, s.usertz
FROM sysuser AS s
WHERE strpos(s.userid, 'Z') > 0 OR (strpos(s.userlang, 'en') - 1) > 0 OR (s.cuser LIKE 'start%') OR ((s.muser IS NOT NULL) AND (s.muser LIKE '%end')) 


 十、Table record Row to Col

1.Linq

2.Lambda

代码如下: 

#region RowToCol
        // a. Linq
        var rowToCol = from m in table1
                       join d in table2 on m.Userid equals d.Userid
                       join d2 in table3 on d.Roleid equals d2.Id
                       group d2 by new { m.Userid } into g
                       select new
                       {
                           UserID = g.Key.Userid,
                           RoleNames = string.Join(",", g.Select(p => p.Rolename))
                       };
        rowToCol.ToList();

        // b. Lambda
        rowToCol = table1.Join(table2, m => m.Userid, d => d.Userid, (m, d) => new
        {
            Userid = m.Userid,
            Roleid = d.Roleid
        }).Join(table3, m => m.Roleid, d => d.Id, (m, d) => new
        {
            Userid = m.Userid,
            Roleid = m.Roleid,
            Rolename = d.Rolename
        }).GroupBy(a => new { a.Userid }).Select(g => new
        {
            UserID = g.Key.Userid,
            RoleNames = string.Join(",", g.Select(p => p.Rolename))
        });
        rowToCol.ToList();

#endregion

生成SQL:

SELECT s.userid AS "UserID", COALESCE(string_agg(s1.rolename, ','), '') AS "RoleNames"
FROM sysuser AS s
INNER JOIN sysuserrole AS s0 ON s.userid = s0.userid
INNER JOIN sysrole AS s1 ON s0.roleid = s1.id
GROUP BY s.userid

SELECT s.userid AS "UserID", COALESCE(string_agg(s1.rolename, ','), '') AS "RoleNames"
FROM sysuser AS s
INNER JOIN sysuserrole AS s0 ON s.userid = s0.userid
INNER JOIN sysrole AS s1 ON s0.roleid = s1.id
GROUP BY s.userid 


 十一、Table record Row to Col left join

1.Linq

2.Lambda

代码如下: 

#region RowToCol left join
        // a. Linq
        rowToCol = from m in table1
                   join t1 in table2 on m.Userid equals t1.Userid into t1group
                   from d in t1group.DefaultIfEmpty()
                   join t2 in table3 on d.Roleid equals t2.Id into t2group
                   from d2 in t2group.DefaultIfEmpty()
                   group d2 by new { m.Userid } into g
                   select new
                   {
                       UserID = g.Key.Userid,
                       RoleNames = string.Join(",", g.Select(p => p.Rolename))
                   };
        rowToCol.ToList();

        // b. Lambda
        rowToCol = table1.SelectMany(a => table2.Where(b => b.Userid == a.Userid).DefaultIfEmpty(),
                        (m, n) => new { Userid = m.Userid, roleid = n.Roleid })
            .SelectMany(a => table3.Where(b => b.Id == a.roleid).DefaultIfEmpty(),
                        (m, n) => new { Userid = m.Userid, RoleID = m.roleid, Rolename = n.Rolename })
            .GroupBy(a => new { a.Userid }).Select(g => new
            {
                UserID = g.Key.Userid,
                RoleNames = string.Join(",", g.Select(p => p.Rolename))
            });
        rowToCol.ToList();

#endregion

生成SQL:

SELECT s.userid AS "UserID", COALESCE(string_agg(COALESCE(s1.rolename, ''), ','), '') AS "RoleNames"
FROM sysuser AS s
LEFT JOIN sysuserrole AS s0 ON s.userid = s0.userid
LEFT JOIN sysrole AS s1 ON s0.roleid = s1.id
GROUP BY s.userid

SELECT s.userid AS "UserID", COALESCE(string_agg(COALESCE(s1.rolename, ''), ','), '') AS "RoleNames"
FROM sysuser AS s
LEFT JOIN sysuserrole AS s0 ON s.userid = s0.userid
LEFT JOIN sysrole AS s1 ON s0.roleid = s1.id
GROUP BY s.userid



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

相关文章

【数据结构】链表C语言编写的,它定义了一个链表,并实现了一些基本的链表操作,如创建新节点、插入节点、清空链表、输出链表以及查找节点

#include <stdio.h> // 引入标准输入输出库&#xff0c;用于输入输出操作 #include <stdlib.h> // 引入标准内存分配库&#xff0c;用于动态内存分配 #include <time.h> // 引入标准时间库&#xff0c;用于使用随机数生成函数 // 定义常量DL为…

Qt MinGW / MSVC

MinGW/MSVC的关系 MinGW / MSVC.dll / .lib / .a 的关系 MinGW / MSVC Qt 中有两种方式编译&#xff1a;一种是MinGW &#xff0c;另一种MSVC&#xff0c;是两种不同的编译器。 MinGW(Minimalist GNUfor Windows)&#xff0c;它是一个可自由使用和自由发布的Windows特定头文件…

ELK集群搭建流程(实践可用)

一、概述 ELK 是一个由三个开源软件工具组成的数据处理和可视化平台&#xff0c;包括 Elasticsearch、Logstash 和 Kibana。这些工具都是由 Elastic 公司创建和维护的。 Elasticsearch 是一个分布式的搜索和分析引擎&#xff0c;可以将大量数据存储在一个或多个节点上&#xf…

一个新工具 nolyfill

名字的意思&#xff0c; 我自己的理解 no(po)lyfill 正如它的名字, 不要再用补丁了, 当然这里说的是过时的补丁。 polyfill 是补丁的意思 为什么要用这个插件 文档原文: 当您通过安装最新的 Node.js LTS 来接受最新的功能和安全修复时&#xff0c;像eslint-plugin-import、…

作为产品经理,有必要考PMP或者NPDP么?

产品经理的核心竞争力是什么? 三点&#xff1a;知识、能力和决策 懂得越多&#xff0c;能力越强&#xff0c;决策越正确&#xff0c;核心竞争力越强。一般来说&#xff0c;看的越多&#xff0c;做的越多&#xff0c;实践出经验才是王道&#xff0c;但是&#xff0c;总有看不…

第4章 内核模块实验(iTOP-RK3568开发板驱动开发指南 )

在上一章节我们编写了最简单的helloworld驱动程序。有了驱动程序以后&#xff0c;要如何编译并使用驱动呢。编译驱动有俩种方法&#xff0c;分别是将驱动编译成内核和将驱动编译成内核模块。我们先来学习如何将驱动编译成内核模块、 4.1 设置交叉编译器 1 下载网盘资料下的交…

Qt打开及创建项目,运行程序(1)

安装之后&#xff0c; 1.文件->新建文件或项目 2.Application->Qt Widgets Application 3.自己设置名称和路径 4.这一步非常非常重要&#xff0c;要选择编译器&#xff0c;&#xff08;MinGW是可以在Qt里用&#xff0c;如果想与VS交互&#xff0c;要选择MSVC&#xff09…

log4j2Scan.jar在log4j漏洞复现中的使用

首先在burp中安装该插件 装完后浏览器打开一个有log4j漏洞的网站 不需要开启拦截&#xff0c;插件就可以自动检测该网站有没有log4j的漏洞 有号说明发现了漏洞