EF列表分页查询(单表、多表),排除参数为空的条件

13 篇文章 0 订阅

在日常使用EF框架查询数据库时,有时传入的参数为空,那么我们应该把该条件排除,不应列入组装的sql中,本篇文件以分页查询为例介绍EF框架的单表、多表的多条件查询,参数为空时排除条件。

首先我们要有派生自DBContext类的数据上下文类,这个类代表数据库连接和数据库模型

public class MyDbContext : DbContext
{
    public DbSet<人员信息> PersonBasic{ get; set; }
    public DbSet<考核信息> Assess{ get; set; }
}

两个示例的实体类型

用于映射到数据库表的实体类型。也就是数据库的表和字段

public class 人员信息
{
    public int Id { get; set; }//id
    public string Name { get; set; }//姓名
    public string Sex{ get; set; }//性别
    public string Age{ get; set; }//年龄
    public string IdNumber{ get; set; }//身份证号   与B表身份证相同  可关联
    public string State{ get; set; }//状态
    //...
}
public class 考核信息
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Sex{ get; set; }
    public string Age{ get; set; }
    public string IdNumber{ get; set; }//身份证号
    [Column(TypeName = "date")]
    public DateTime? Time{ get; set; }//考核时间
    public string OrganCode{ get; set; }//机构编号
    
    //...
}

入参实体

public class InputDto{
		public string SearchText{get;set;}//一个参数可查询多个条件
		public string Sex{get;set;}
		public string StartTime{get;set;}
		public string EndTime{get;set;}
		public string OrganCode{get;set;}
		public string State{get;set;}
		public string Number{get;set;}
		public int PageIndex{get;set;}
		public int PageIndex{get;set;}
}

结果返回实体

public class OutPutDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Sex{ get; set; }
    public string Age{ get; set; }
    public string State{ get; set; }
    //...
}

使用dbcontext上下文类进行查询


namespace Test
{
    public class AppServiceTest
    {
        private readonly MyDbContext _context;
        public AppServiceTest(MyDbContext context)
        {
            this._context = context;
        }
		/// <summary>
        /// 获取列表 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [Route("api/Test/GetList")]
        public dynamic GetListAsync(InputDto input)
        {
                return GetEFList(input,_context); 
        }
	}
}
using (var context = new MyDbContext())
{
    var entities = context.Entities.ToList();
}

		/// <summary>
        /// ef查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public PagedResultDto<OutPutDto> GetEFList(InputDto input, MyDbContext _context)
        {
			//机构信息传来的形式为  37,38,39
            string[] organ = input.OrganCode?.Split(',');

            IQueryable<考核信息> query = null;
            if (string.IsNullOrWhiteSpace(input.State))
            {
                DbSet<考核信息> db = _context.考核信息;
                // 定义查询条件    单表   lambda表达式查询
                //解释一下改表达式的意思,首先db表示数据库的“考核信息”表
                //whereif用于判断input实体传来的参数是否为空,如果不为空则拼接该条件
                //第一个whereif中代表着"姓名"字段开头包含input.SearchText传来的参数,当然也可以使用Contains方法,完整意思为“姓名”包含参数 或 “身份证号”包含参数
                //whereif.whereif 就代表着一直and
                //第二个whereif代表,如果传开的参数不为空,那拼接sql  性别=传来的参数   例:sex='男'
                //第三个whereif,参数不为空时时间大于等于传来的参数,由于数据库是datetime类型所以要转换
                //第四个whereif 同上
                //第五个whereif 代表数据库中的in  方法的开始先将OrganCode转换为数组然后organ.Contains(x.OrganCode)使用
                //最后一个whereif 如果Number大于1  那么根据身份证去重(一个人会有多条数据) 查最大的id
                 query = db
                            .WhereIf(!string.IsNullOrWhiteSpace(input.SearchText), x => x.姓Name.StartsWith(input.SearchText) || x.IdNumber.StartsWith(input.SearchText))
                             .WhereIf(!string.IsNullOrWhiteSpace(input.Sex), x => x.Sex == input.Sex)
                             .WhereIf(!string.IsNullOrWhiteSpace(input.StartTime), x => x.Time >= DateTime.Parse(input.StartTime))//input.StartTime.Adapt<DateTime>()
                             .WhereIf(!string.IsNullOrWhiteSpace(input.EndTime), x => x.Time <= DateTime.Parse(input.EndTime))
                             .WhereIf(!string.IsNullOrWhiteSpace(input.OrganCode), x => organ.Contains(x.OrganCode))
                             .WhereIf(input.Number > 0, x => db.GroupBy(y => y.IdNumber)
                                     .Where(group => group.Count() > input.Number)
                                     .Select(group => group.Max(y => y.Id))
                                     .Contains(x.Id)).OrderByDescending(a=>a.Id);
					//将以上表达式转换为sql为
					//select * from 考核信息 where (Name like '王%' or IdNumber like '王%') and   Sex='男' and OrganCode in('37','38') and Id in(select max(Id) from 考核信息 group by IdNumber having count(*)>1) Order By Id Desc
					//当然如果Number参数为0对应的sql为
					//select * from 考核信息 where (Name like '王%' or IdNumber like '王%') and   Sex='男' and OrganCode in('37','38') Order By Id Desc
					
            }
            else
            {
                DbSet<考核信息> kh = _context.考核信息;
                DbSet<人员信息> basic = _context.人员信息;
                //  定义查询   多表   linq查询
                 query = from a in kh 
                            join b in basic on a.IdNumber equals b.IdNumber
                            where
                                (string.IsNullOrWhiteSpace(input.SearchText) || a.Name.StartsWith(input.SearchText) || a.IdNumber.StartsWith(input.SearchText)) &&
                                (string.IsNullOrWhiteSpace(input.Sex) || a.Sex == input.sex) &&
                                (string.IsNullOrWhiteSpace(input.StartTime) || a.Time >= DateTime.Parse(input.StartTime)) &&
                                (string.IsNullOrWhiteSpace(input.EndTime) || a.Time <= DateTime.Parse(input.EndTime)) &&
                                (string.IsNullOrWhiteSpace(input.State) || b.State == input.State) &&
                                (input.Number <= 0 || (from x in kh
                                                     group x by x.IdNumber into g
                                                     where g.Count() > 1
                                                     select g.Max(x => x.Id)).Contains(a.Id))
                         orderby a.Id descending
                         select a;
						//以上linq表达式对应的sql为
						//select * from 考核信息 a Inner JOIN 人员信息 b  ON a.IdNumber = b.IdNumber where (a.Name like '王%' or a.IdNumber like '王%') and a.Sex='男' and a.OrganCode in('37', '38') and a.Id in(select max(Id) from 考核信息 group by IdNumber having count(*)>1) Order By a.Id Desc
						//当然如果number为0时
						//select * from 考核信息 a Inner JOIN 人员信息 b  ON a.IdNumber = b.IdNumber where (a.Name like '王%' or a.IdNumber like '王%') and a.Sex='男' and a.OrganCode in('37', '38')  Order By a.Id Desc
					


				//  定义查询   多表   lambda查询
					//query= (IQueryable<考核信息>)followUp.Join(basic,a=>a.IdNumber,b=>b.IdNumber,(a,b)=>new { a,b})
					//.WhereIf(!string.IsNullOrWhiteSpace(input.SearchText), x => x.a.Name.StartsWith(input.SearchText) || x.a.IdNumber.StartsWith(input.SearchText))
                //            .WhereIf(!string.IsNullOrWhiteSpace(input.Sex), x => x.a.Sex == input.Sex)
                //            .WhereIf(!string.IsNullOrWhiteSpace(input.StartTime), x => x.a.StartTime >= DateTime.Parse(input.StartTime))//input.StartTime.Adapt<DateTime>()
                //            .WhereIf(!string.IsNullOrWhiteSpace(input.EndTime), x => x.a.EndTime <= DateTime.Parse(input.EndTime))
                //            .WhereIf(!string.IsNullOrWhiteSpace(input.State), x =>x.b.State == input.State)
                //            .WhereIf(input.Number != null && input.Number > 0, x => followUp.GroupBy(y => y.IdNumber)
                //                    .Where(group => group.Count() >= input.Number)
                //                    .Select(group => group.Max(y => y.Id))
                //                    .Contains(x.a.Id)).OrderByDescending(x => x.a.Id);
					
				
            }

            int count= query.Count();//统计总行数

            // 分页查询数据
            var pageIndex = input.PageIndex;
            var pageSize = input.PageSize;
            var pageData = query.Skip(pageSize * (pageIndex - 1)).Take(pageSize).ToList();
			
			//这里使用了Mapster中间件可以在包控制管理工具中安装   然后using Mapster;
			//意思是将pageData映射成OutPutDto
            List<OutPutDto> aaa = pageData.Adapt<List<OutPutDto>>();
            return new {items=pageData,total=count};
        }

end

看完此篇文章后是不是感觉瞬间豁然开朗?

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香煎三文鱼

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值