var query = from template in this.templateRepository.GetAll().AsNoTracking()
join templateCollect in this.templateCollectRepository.GetAll().AsNoTracking()
on template.Id equals templateCollect.TemplateId
join user in this.UserManager.Users.Select(q=>new {q.Id,q.Name,q.HeadUrl }) on template.CreatorUserId equals user.Id
join schoolInfo in this.schoolInformationRepository.GetAll().AsNoTracking()
on template.SchoolId equals schoolInfo.Id into SInfo
from s in SInfo.DefaultIfEmpty()
join quotaClass in this.quotaClassRepository.GetAll().AsNoTracking()
on template.AwardAttributeId equals quotaClass.Id
select new
{
Id = template.Id,
ActivityName = template.ActivityName,
}
我想在join user 的时候只查询user的id,name,HeadUrl字段,然后作为子表再和其他表关联,但是生成的sql语句查询user表的时候还是查询出了所有字段然后再和其他表关联的,是我写的不对还是不支持这样操做,如果想达到我要求的该咋写?
建议将
this.UserManager.Users.Select(q=>new {q.Id,q.Name,q.HeadUrl })
与
select new
{
Id = template.Id,
ActivityName = template.ActivityName,
}
放到一起 select
放到一起的话查询user表的子查询就不是查的所有字段了吗?最后的select不是生成sql语句最外层的select字段么,并不影响user子查询表里的输出字段吧?
我其实就是想查每个子查询的时候只查用到的字段,然后再和其他表关联,不知道子查询只查部分字段是否会提高点性能
@冷水寒冰: 在 ToListAsync()
时 EF 才会把 LINQ 翻译为 SQL 语句
@dudu: 这个我大概知道,但是我在上边写关联的时候只是定义查询哪些字段,还没到实际查寻呢吧?再说我再上边没法调用tolist(),调用完再关联执行就报错了
@冷水寒冰: 并没有用到 user 表的数据 ,即使没有 .Select(q=>new {q.Id,q.Name,q.HeadUrl })
,通常情况下也不会查询 user 的所有字段
@dudu: 但是我记录的生成的sql语句的确是先从user表查询出所有字段,然后作为一个表再和其他表关联的
@冷水寒冰: 建议检查一下 User 的实体关系定义
@dudu: 其他实体也一样,我的实体都单个的,和表一对一的,没有主从实体的关联,所有的关联都是查询的时候linq关联。
linq用的不好就写sql吧,没必要纠结;
你上面的查询把User取来来干什么?
建议你拆分一下查询,在不参与数据过滤的前提下,少量多次提取数据。
比如你上面的查询,可以先把数据查出来,再跟据用户id集合提取对应的用户信息,在程序中完成组装。
我觉得 dudu 的建议可以一试,或者你先把
this.UserManager.Users.Select(q=>new {q.Id,q.Name,q.HeadUrl }) 加个ToList() 试试看,这可能是一个“bug”,EF 生成的语句并是那么完美,尽量避免这种写法,很多不可控的地方,后期EF版本升级容易翻车。