有关一个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,怎么实现不报错,又保证之前的查询效率。
...全文
209 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)) });
360等软件会报安全未知软件,请允许执行。 v1.1.2014.10更新 1、增加了表表之间的关系,通过外键关系的实体类访问更方便 2、增加了DAL的Insert函数。其它基本操作在后续版本中实现. 3、增加了部分表、字段的中文注释功能等; 4、修正了一部分错误; 5、增加一个简单的示例; 软件件适用: 1、根据SQL数据库生成实体文件类,类似于SqlMetal和动软代码生成器,但是相比较SqlMetal简化了较多的不常用的函数(我认为的),成员变量支持数据库字段注释,一个表对应一个文件,不像sqlmetal如果数据库表和字段多了,一下生成几千行一个文件。 2、数据库操作采用的LINQ TO SQL,小规模的应当问题不大吧,实现了INSERT,UPDATE,EXIST,GET方法。DELETE比较简单,自己写吧,写在LINQ里面,我觉得不划算。 3、相比较动软代码生成器,生成代码除系统组件(System命名空间)外,不调用任何第三方组件。 4、可以做B\S的,也可以做C\S的,生成的示例以B\S。 5、纯绿色软件,无需要安装,而且只有一个文件! 运行环境: 1、64位操作系统,32位的没有测试过。需要.net fromwork4.0支持,当然还要一个数据库才能生成。 2、数据库SQL2008Express版本以上,高于此版本应当当没有问题。低于此版本,我只能呵呵的,说不定可以…… 3、数据库配置方式引用了Discuz!NT的做法,没有写在Web.Config文件里面。稍作修改你可以完全写出其它类似的配置文件。可惜,Discuz!NT现在不做了!在此深表怀念! 4、建议每个表都要定义主键或唯一键,建立索引否则生成的LINQ语句将无法完成查询。 v1.1.2014.10程序校验码: MD5 :3F7BE759F0BE7E86236620D57D4472FE SHA1 :69BABBBA33D516FA1AD0068F44C145989103FB4B CRC32 :EAD371EA 如果需要交流,加群:点软件上面的QQ直接加哦! 本软件适用开发小软件吧,大软件不知道性能怎么样,欢迎高手指点

111,120

社区成员

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

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

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