EF Core如何直接映射查询结果到含RepeatedField的gRPC生成类?
直接将EF Core查询映射到gRPC的RepeatedField类型
你遇到的核心问题是:gRPC生成的RepeatedField<T>无法直接在EF Core的LINQ查询中赋值——因为EF Core会尝试将LINQ表达式翻译成SQL,而RepeatedField的实例操作无法被SQL解析。下面是两种可行的解决方案:
方案1:先查询匿名类型到内存,再映射到UserResponse
先从数据库拉取所需的基础数据(用匿名类型承载),再在内存中构造UserResponse并填充RepeatedField:
var data = context.Users .Where(t => t.Id == id) // 注意此处是相等判断==,不是赋值= .Select(t => new { t.Id, t.Name, Roles = t.Roles.Select(r => r.Name) }) .AsEnumerable() // 将查询切换到本地内存执行 .Select(t => { var response = new UserResponse { Id = t.Id, Name = t.Name }; response.Roles.AddRange(t.Roles); return response; }) .FirstOrDefault();
方案2:利用RepeatedField的构造器(需确认版本支持)
部分版本的gRPC工具生成的RepeatedField<T>支持接收IEnumerable<T>的构造器,可直接在内存中实例化:
var data = context.Users .Where(t => t.Id == id) .Select(t => new { t.Id, t.Name, Roles = t.Roles.Select(r => r.Name).ToList() }) .AsEnumerable() .Select(t => new UserResponse { Id = t.Id, Name = t.Name, Roles = new RepeatedField<string>(t.Roles) }) .FirstOrDefault();
关键注意点
- 必须先调用
AsEnumerable()将数据拉到本地内存,再进行RepeatedField的操作——否则EF Core会尝试将RepeatedField的构造或AddRange操作翻译成SQL,导致报错。 - 原代码中
Where(t => t.Id = id)是赋值操作,需改为相等判断==,否则会出现编译错误或逻辑错误。
内容的提问来源于stack exchange,提问作者KeyKiller
相关产品推荐
相关产品推荐

