Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用多级嵌套匿名类型接收多级GroupBy结果时,会抛出Member Not Found的异常 #244

Open
linzhary opened this issue May 10, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@linzhary
Copy link

linzhary commented May 10, 2023

假设现在有以下实体:

public class TestEntity
{
    public Id { get; set; }
    public DateTime Time { get; set; }
    public int Type { get; set; }
}

分表路由使用按月分表。

此时如果我有以下查询(注意:这里该查询触发了跨表查询逻辑)

var begin = DateTimeOffset.UtcNow.Date.AddDays(-40).DateTime;
await dbContext.Set<TestEntity>()
.Where(x=>x.Time >= begin)
.GroupBy(x => x.Time)
.Select(x => new
{
    Time = x.Key,
    Groups = x.GroupBy(s => s.Type)
        .Select(s =>
        {
            Type = s.Key,
            Count = s.Count()
        })
})
.ToListAsync();

该查询会导致ShardingCore.Extensions.StringFieldOrderExtension.GenerateSelector方法中,抛出如下异常
image
原因似乎是匿名类型在Visit表达式的时候将GroupsType作为selectGroupKeyProperties传入了OrderWithExpression,但是未在顶层类型中找到该字段。

而当我声明一个Class来接收Select结果时,该查询可以正常执行,根据代码来看
image
匿名类型接收结果走了NewExpression逻辑
声明一个Class接收结果走了MemberInitExpression逻辑

该问题导致的结果是使用多级嵌套匿名类型接收多级GroupBy查询结果时,查询无法正常工作

@linzhary
Copy link
Author

linzhary commented May 10, 2023

根据我本地调试结果
NewExpression逻辑会产生三个sort字段 Time asc,Groups asc,Type asc
MemberInitExpression逻辑会产生一个sort字段 Time asc

@xuejmnet
Copy link
Collaborator

@linzhary 这个我后续看下应该是解析表达式的时候没考虑到位导致的

@xuejmnet xuejmnet added the bug Something isn't working label May 10, 2023
@xuejmnet
Copy link
Collaborator

分片聚合默认有两种一种是memory一种是stream,stream的要求是group key和order key顺序一致,所以会默认吧聚合select当作order重写sql表达式

@xuejmnet
Copy link
Collaborator

xuejmnet commented May 10, 2023

stream性能好内存占用少,所以会尽可能的使用stream

@linzhary
Copy link
Author

目前我的解决方案是使用单级GroupBy多字段查询到内存中后再做数据处理,类似这样是可以正常查询的

var begin = DateTimeOffset.UtcNow.Date.AddDays(-40).DateTime;
var groupResult = await dbContext.Set<TestEntity>()
.Where(x=>x.Time >= begin)
.GroupBy(x => new { x.Time, x.Type })
.Select(x => new
{
    Time = x.Key.Time,
    Type = x.Key.Type,
    Count = s.Count()
})
.ToListAsync();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants