实战 EF(LINQ) 如何以子查询的形式来 Join
Posted music
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实战 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 )
谢谢浏览!
以上是关于实战 EF(LINQ) 如何以子查询的形式来 Join的主要内容,如果未能解决你的问题,请参考以下文章