有关一个linq语句的问题,求指点

aierda 2020-03-16 10:59:29
我起初在系统中使用的是ef core 2.1版本,下面的这条linq语句没有问题。

var query = (from a in _aRepository.GetAll()
.Where(t => t.TenantID.ToString() == teantID)
join b in _bRepository.GetAll()
on a.bID equals b.Id
select new B
{
Id = b.Id,
ParentID = b.ParentID,
Number = b.Number,
Name = b.Name,
UserName = a.StaffName
}).GroupBy(t => t.UserName).Select(t => new BDto()
{
Id = string.Join(",", t.Select(t => t.Id)),
ParentID = string.Join(",", t.Select(t => t.ParentID.ToString())),
Number = string.Join(",", t.Select(t => t.Number.ToString())),
UserName = c.Key,
Name = string.Join(",", t.Select(t => t.Name))
});

但是升级ef core3.1之后呢,这条查询语句报错了,说是“未将对象引用到实例”。错误的地方出现在
t.Select(t => t.Id)中,后来我查了些资料,对这条linq语句进行了修改,即在GroupBy之前加上AsEnumerable<B>()
最后变成这样:

var query = (from a in _aRepository.GetAll()
.Where(t => t.TenantID.ToString() == teantID)
join b in _bRepository.GetAll()
on a.bID equals b.Id
select new B
{
Id = b.Id,
ParentID = b.ParentID,
Number = b.Number,
Name = b.Name,
UserName = a.StaffName
}).AsEnumerable<B>().GroupBy(t => t.UserName).Select(t => new BDto() //AsEnumerable<B>()为新增
{
Id = string.Join(",", t.Select(t => t.Id)),
ParentID = string.Join(",", t.Select(t => t.ParentID.ToString())),
Number = string.Join(",", t.Select(t => t.Number.ToString())),
UserName = c.Key,
Name = string.Join(",", t.Select(t => t.Name))
});

这样的确是不报错了,但是我发现在toList之前,这条语句已经获取结果了,也就是说AsEnumerable已经访问了数据库了
。假如我要做分页查询,这种效率应该会比较低。因为它是把数据先从数据库加载了,然后再分页的,不是吗?
问题1,为什么升级ef core后会报错
问题2,怎么实现不报错,又保证之前的查询效率。
...全文
186 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
闪耀星星 2020-03-17
  • 打赏
  • 举报
回复
一般不要升级,除非你要用到新的优化,否则可能需要修改自己的代码
楠小南 2020-03-16
  • 打赏
  • 举报
回复
也是晕了,EF 不要套任何函数,哪怕是 Totring() 也不要,为什么?因为他要生成表达式树,如果有关系就搞关系,不然就分开查询再组装, 你这样搞很容易全表查询的,来个笛卡尔乘积 你还不晕了,这个坑相信很多新手都会踩,只要是复杂查询就要用 sql profiler 去监控一下就知道了
楠小南 2020-03-16
  • 打赏
  • 举报
回复
引用 4 楼 aierda 的回复:
[quote=引用 1 楼 楠小南 的回复:]
也是晕了,EF 不要套任何函数,哪怕是 Totring() 也不要,为什么?因为他要生成表达式树,如果有关系就搞关系,不然就分开查询再组装, 你这样搞很容易全表查询的,来个笛卡尔乘积 你还不晕了,这个坑相信很多新手都会踩,只要是复杂查询就要用 sql profiler 去监控一下就知道了

不要套任何函数?我原先也是没有使用任务的函数啊,但是升级后会报错。如果不加AsEnumerable的话,请问你有更好的办法吗?[/quote]

AsEnumerable 相当于tolist() 了! 没办法,join 查出数据后 即可,后面的让程序去做 不要啥都往EF 上面怼。另外一个就是 你的分组有点多余了,没有聚合函数 你分了也是多余的,不想重复你完全可以用 Distinct



正怒月神 2020-03-16
  • 打赏
  • 举报
回复
引用 3 楼 aierda 的回复:
不能,还是报错 而且这样,效果也不高啊,也是查询出全部数据后,再分页
那就不知道了。我没用过core。
aierda 2020-03-16
  • 打赏
  • 举报
回复
引用 1 楼 楠小南 的回复:
也是晕了,EF 不要套任何函数,哪怕是 Totring() 也不要,为什么?因为他要生成表达式树,如果有关系就搞关系,不然就分开查询再组装, 你这样搞很容易全表查询的,来个笛卡尔乘积 你还不晕了,这个坑相信很多新手都会踩,只要是复杂查询就要用 sql profiler 去监控一下就知道了

不要套任何函数?我原先也是没有使用任务的函数啊,但是升级后会报错。如果不加AsEnumerable的话,请问你有更好的办法吗?
aierda 2020-03-16
  • 打赏
  • 举报
回复
引用 2 楼 正怒月神 的回复:
这样能运行吗
var query = (from a in _aRepository.GetAll()
.Where(t => t.TenantID.ToString() == teantID)
join b in _bRepository.GetAll()
on a.bID equals b.Id
select new B
{
Id = b.Id,
ParentID = b.ParentID,
Number = b.Number,
Name = b.Name,
UserName = a.StaffName
}).GroupBy(t => t.UserName).ToList().Select(t => new BDto() //AsEnumerable<B>()为新增
{
Id = string.Join(",", t.Select(t => t.Id)),
ParentID = string.Join(",", t.Select(t => t.ParentID.ToString())),
Number = string.Join(",", t.Select(t => t.Number.ToString())),
UserName = c.Key,
Name = string.Join(",", t.Select(t => t.Name))
});

不能,还是报错

而且这样,效果也不高啊,也是查询出全部数据后,再分页
正怒月神 2020-03-16
  • 打赏
  • 举报
回复
这样能运行吗 var query = (from a in _aRepository.GetAll() .Where(t => t.TenantID.ToString() == teantID) join b in _bRepository.GetAll() on a.bID equals b.Id select new B { Id = b.Id, ParentID = b.ParentID, Number = b.Number, Name = b.Name, UserName = a.StaffName }).GroupBy(t => t.UserName).ToList().Select(t => new BDto() //AsEnumerable<B>()为新增 { Id = string.Join(",", t.Select(t => t.Id)), ParentID = string.Join(",", t.Select(t => t.ParentID.ToString())), Number = string.Join(",", t.Select(t => t.Number.ToString())), UserName = c.Key, Name = string.Join(",", t.Select(t => t.Name)) });

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧