码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-12-05 20:31:21      阅读:268      评论:0      收藏:0      [点我收藏+]

标签:join   rabl   index   关联   查询   not   获取   image   也有   

如题,大多数网上关于 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

标签:join   rabl   index   关联   查询   not   获取   image   也有   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!