实战 EF(LINQ) 如何以子查询的形式来 Join

如题,大多数网上关于 LINQ Join 的示例都是以 from x in TableA  join ... 这样的形式,这种有好处,也有劣势,就是在比如我们使用的框架如果已经封装了很多方法,比如分页方法。而我们的业务方法只需要在 Service 层调用框架的分页方法,同时注入条件拼接的委托就可以了。而这时候,为了简单,就会以调用 Join() 方法来实现关联查询,外部看起来好像是子查询,而实际上 Entity Framework 生成 SQL 时,还是会以 Inner join 的形式来生成 SQL 语句,但不管怎样,我们还是解决了我们的实际需求,也就可以说成功了。

1. 数据库

假设有 2 张表。Person 表和 City 表。Person 表的 CityID 关联 City 表的 ID。

City 表:

Person 表:

2. 需求

现在,前台界面有一个 checkbox 复选框组,列出所有的城市,然后用户可以选择一个或多个,比如“深圳”和“北京”,分页列出对应的人员。注意,前台界面只需要列出 Person 的 Id 和 Name 就可以了,不需要列出城市的名称。

3. 代码

PersonQueryCondition.cs

    public class PersonQueryCondition
    {
        public IEnumerable<string> CityNameList { get; set; }
    }

PersonService.cs

    public class PersonService : IPersonService
    {
        private readonly IRepository<Person> _personRepository;
        private readonly IRepository<City> _cityRepository;

        public PersonService(IRepository<Person> personRepository,
            IRepository<City> cityRepository
            )
        {
            this._personRepository = personRepository;
            this._cityRepository = cityRepository;
        }

        /// <summary>
        /// 根据城市名称列表获取分页实体
        /// </summary>
        /// <param name="cityIdList"></param>
        /// <returns></returns>
        public List<Person> GetPagedList(PersonQueryCondition queryCondition, int pageIndex, int pageSize, out int recordCount)
        {
            return this._personRepository.GetListPagedByCondition<PersonQueryCondition>(c => c.Id > 0,
                CombineQuery,
                queryCondition,
                pageIndex,
                pageSize,
                out recordCount);
        }

        protected virtual IQueryable<Person> CombineQuery(IQueryable<Person> query, PersonQueryCondition queryCondition)
        {
            if (queryCondition == null)
            {
                return query;
            }
            if (queryCondition.CityNameList != null && queryCondition.CityNameList.Any())
            {
                query = query.Join(_cityRepository.Table, p => p.CityID, c => c.Id, (p, c) => new { Person = p, City = c })
                    .Where(a => queryCondition.CityNameList.Contains(a.City.Name))
                    .Select(c => c.Person);
            }
            return query;
        }
    }

代码解释截图如下:

基类方法如下:

4. 生成 的SQL 语句

SQL 语句如下:

SELECT
    [Extent1].[Id] AS [Id],
    [Extent1].[Name] AS [Name],
    [Extent1].[CityID] AS [CityID]
FROM
    [dbo].[Person] AS [Extent1]
    INNER JOIN [dbo].[City] AS [Extent2] ON [Extent1].[CityID] = [Extent2].[Id]
WHERE
(
    [Extent1].[Id] > 0
)
AND
(
    [Extent2].[Name] IN (N‘深圳‘, N‘北京‘)
)
AND
(
    [Extent2].[Name] IS NOT NULL
)

谢谢浏览!

原文地址:https://www.cnblogs.com/Music/p/linq-join-sample.html

时间: 2024-11-10 21:16:51

实战 EF(LINQ) 如何以子查询的形式来 Join的相关文章

走向面试之经典的数据库基础:二、SQL进阶之case、子查询、分页、join与视图

一.CASE的两种用法 1.1 等值判断->相当于switch case (1)具体用法模板: CASE expression WHEN value1 THEN returnvalue1 WHEN value2 THEN returnvalue2 WHEN value3 THEN returnvalue3  ELSE defaultreturnvalue END (2)具体使用示例: 假设我们有一个论坛网站,其中有一张User表{ UId,Name,Level },Level是一个int类型,代

SQL高级部分一(SET运算符 &amp;&amp; 高级子查询)

一.SET运算符 将多个查询用 SET 操作符连接组成一个新的查询 select employee_id , department_id from emp01 union all --相当于两个集合相加, union A并B ,intersect ,A交B,MINUS 差集,A-B select employee_id , department_id from emp02 SET操作的注意事项 在SELECT 列表中的列名和表达式在数量和数据类型上要相对应 括号可以改变执行的顺序 ORDER B

012:子查询和增删改查

一. 子查询 子查询就是指在一个select语句中嵌套另一个select语句.同时,子查询必须包含括号. MySQL 5.6.x 版本之前,MySQL的子查询性能较差,但是从5.6开始,不存在性能差的问题. select a from t1 where a > any(select a from t2); select a from t1 是外部查询(outer query) (select a from t2) 是子查询(subquery) 一般说来,子查询嵌套于外部查询中,可以将两个或两个以

LINQ之路 7:子查询、创建策略和数据转换

在前面的系列中,我们已经讨论了LINQ简单查询的大部分特性,了解了LINQ的支持计术和语法形式.至此,我们应该可以创建出大部分相对简单的LINQ查询.在本篇中,除了对前面的知识做个简单的总结,还会介绍几种创建更复杂查询的方式,让我们在面对更复杂的场景时也能轻松面对,包括:子查询.创建策略和数据转换. 子查询 在创建一个复杂的查询时,通常我们需要用到子查询.相信大家都记得SQL查询里的子查询,在创建LINQ查询时也是如此.在LINQ中,对于方法语法,一个子查询包含在另外一个查询的lambda表达式

ASP.NET EF(LINQ/Lambda查询)

EF(EntityFrameWork) ORM(对象关系映射框架/数据持久化框架),根据实体对象操作数据表中数据的一种面向对象的操作框架,底层也是调用ADO.NET ASP.NET MVC 项目会自动导入MVC程序集,因为默认.NET环境(GAC)中没有这个程序集 1 create database MyFirstEF 2 on primary 3 ( 4 name='MyFirstEF.mdf', 5 --修改为自己电脑上SQL DB路径 6 filename='E:\ProgramMSSQL

Linq实战 之 Linq to Sql及Entity Framework操作详解

Linq实战 之 Linq to Sql及Entity Framework操作详解 一:linq to db的框架 1. linq to sql 2. linq to ado.net entity framework linq to sql是一个团队 ef 是一个团队... linq to sql => ef 团队. linq to sql 适合一些小型的项目 => sqlserver ef 适合中形的项目,而且可以支持 sqllite,mysql,sqlserver 掌柜的项目开发中:使用的

Linq学习(三)-基本查询

一.本将主要介绍内容 从linq,sql,lambda三个角度比较来学习 select.orderby.分页.group by.distinct.子查询.in的用法 1.select 查询用户和它们的自我介绍 Linq to sql from a in Blog_UserInfo select new { 真实名字=a.RealName, 自我介绍=a.Introduce } sql SELECT [t0].[RealName] AS [真实名字], [t0].[Introduce] AS [自

27. SQL -- TSQL(SELECT语句的使用,子查询,连接,通配符 )(3)

通配符: 通配符一般是通过LIKE 使用的. T-SQL 中支持四种通配符,如表所示: 运算 符 含 义 % 代表零个或多个任意字符 _ 代表一个任意字符 [] 指定范围内的任意单个字符 [^] 不在指定范围内的任意单个字符 例如, "AB%"表示以AB 开始的任意字符串: "_cd"表示以cd 结尾的三个字符的字符串: "[ef]%"表示以e 或f 开始的任意字符串: "[s-v]ing"表示开始是s 到v,结尾是ing,长

sql、linq和lambda查询语句比较inner join和group by组合使用及匿名类型的处理

使用EF自己做的小功能需要遇到inner join和group by组合使用及匿名类型的处理,搜了很多,基本不能满足自己的需要,所以总结了也实现了就自己写出来,已备查看及伙伴查询参考(一般的语句查询就不说了,网络搜索很多) 语句查询的背景(要不直接看语句故估计也够呛):主要想实现类似QQ相册的功能展示,页面展示所有相册列表,主要包括:相册里面的相册个数,相册中的某一个张照片作为相册的默认背景图,相册名,相册描述,删除和编辑功能 sql server:(这个就比较简单) select count(