EF Core - 2.0 和 2.1 发现

    EF Core 目前已经升级到了2.1版本。 但是我之前有个项目是2.0 版本的,今天把sql语句弄出来看以下发现了不少问题。目前是建议如果使用了2.0版本的用户可以升级到2.1 。毕竟2.1还是修复了许多问题的。废话不多说,总结以下下面问题:

一、 2.0版本 Join 之后

   用过Linq To Sql 都知道。如果连接两个表,我这边的例子是:

 

     var query = from p in db.PurchaseProject
                        join e in db.Employee on p.ProjectManagerId equals e.Id into pe
                        from pei in pe.DefaultIfEmpty()
                        select new PurchaseProjectListSearchModel()
                        {
                            Id = p.Id,
                            TenderingNo = p.TenderingNo,
                            ProjectName = p.ProjectName,
                            PurchaseKind = p.PurchaseKind,
                            ProjectManagerId = p.ProjectManagerId,
                            ProjectManagerName = pei.RealName,
                            BidOpenDate = p.BidOpenDate,
                            Remark = p.Remark,
                            AgentName = p.AgentName,
                            CreatedOn = p.CreatedOn,
                            Number = p.Number,
 
                        };
   var listData = query.AsNoTracking().OrderBy(m => m.Id).Skip(0).Take(10).ToList();

      我们用Miniprofiler 来查看以下生产的sql语句如下:

 

     没错,我们是使用了left join,但是程序并没有帮我们翻译成分页语句。这个问题在2.1 版本偷偷的得到改善,而微软官方文档却没有做出修改的解释。

 

    二、 2.1 版本Group By 受到干扰

     看下下面的代码:

     

            var d7 = (from n in db.TestBF.Where(m => m.Num1 > 1)
                      group n by n.Number into g
                      select new TestModel()
                      {
                          CreateTime = g.Min(m => m.CreateOn),
                          Total = g.Min(m => m.Num1) + g.Min(m => m.Num2),
                      }).ToList();

 真正的执行的语句是:

  

 

   这个我们很容易理解,就是正常的一个Group by ;下面我们把查询的代码修改一下:

   

   var d7 = (from n in db.db.Where(m => m.Num1 > 1)
                      group n by n.Number into g
                      select new TestModel()
                      {
                          CreateTime = g.Min(m => m.CreateOn),
                          Total = g.Min(m => m.Num1) + g.Min(m => m.Num2),
                          Num = g.Sum(m => m.Num1 ?? 0)
                      }).ToList();

      数据库中的Num1是Int? 类型,在使用双目运算符??以后我们看一下真正执行的sql语句:

让我们惊讶的是没有了Group by 而是把所有数据查询出来在内存里面执行了。还有简单的一些时间转换ToString()

   

            var d7 = (from n in db.TestBF.Where(m => m.Num1 > 1)
                      group n by n.Number into g
                      select new TestModel()
                      {
                          CreateTime = g.Min(m => m.CreateOn),
                          Total = g.Min(m => m.Num1) + g.Min(m => m.Num2),
                          //Num = g.Sum(m => m.Num1 ?? 0)
                          TimeStr = g.Min(m => m.CreateOn.ToString())
                      }).ToList();

 最终都会把group by 干扰掉。当然解决方法是把数据库字段原封不动的映射到外部的Model,然后再把查询出来的数据进行转换,不要轻易在select里面进行函数使用,当然了有些语法还是支持的,比如:

 

            var d82 = (from n in db.TestBF
                       select new TestModel()
                       {
                           CreateTime = n.CreateOn,
                           Total = n.Num1 + n.Num2,
                           Num = n.Num1.GetValueOrDefault(0),
                           TimeStr =  n.CreateOn.ToString()
                          
                       }).Skip(1).Take(2).ToList();

 如果是分页的话:

 

接下来看下Join语句之后进行一个group by ,这也是我们平时做查询经常用到的

 

     using (var db = new MyDbContext())
            {
                var query = from s in db.Student
                            join c in db.SC on s.sid equals c.sid into sc
                            from sci in sc.DefaultIfEmpty()
                            group new { s,sci} by new { s.sid, s.sname } into g
                            select new
                            {
                                sid = g.Key.sid,
                                sname = g.Key.sname,
                                //scount = g.Count(),
                                //total = g.Sum(m=>m.sci!=null ? m.sci.score : 0)
                            };

                var data = query.ToList();
            }

 

 

 最终,EF又让我们失望了,这个查询就是查询所有同学的学号、姓名、选课数、总成绩。Student是学生表,SC是学生课程成绩表。所有,EF Core还有一段路要走...

执行语句并不一定是我们语法想得到的。所以....

好了,今天分享就到这。

 

posted @ 2018-11-12 09:25  UpOcean  阅读(390)  评论(0编辑  收藏  举报