【问题标题】:'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type - on EF API Call'System.Linq.Expressions.ParameterExpression' 必须返回相同类型的非空值 - 在 EF API 调用上
【发布时间】:2020-07-11 08:56:37
【问题描述】:

我正在尝试使用以下代码填充 .NET Core 3.1 API 控制器(使用 Entity Framework Core)中类的 int 属性:

[HttpGet("Get")]
public async Task<ActionResult<IEnumerable<Partner>>> Get()
{
     List<Device> devices = await _context.Devices.ToListAsync();
     List<Partner> items = await (from p in _context.Partners
               select new Partner
               {
                Id = p.Id,
                Name = p.Name,
                FiscalCode = p.FiscalCode,
                Licenses = p.Licenses,
                Erp = p.Erp,
                ErpName = p.Erp == 1 ? "Erp 1" : "Erp 2",
                Devices = devices.Count(k => k.PartnerId == p.Id)
                }).OrderBy(k => k.Name).ToListAsync();

      return items;
}

Devices = devices.Count(k =&gt; k.PartnerId == p.Id) 行生成以下错误: System.InvalidOperationException: When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type

我做错了什么?

提前致谢

【问题讨论】:

标签: c# entity-framework-core asp.net-core-3.1 .net-core-3.1


【解决方案1】:

我认为您正在尝试在数据库中进行 joingroup by。这样你只需在数据库中查询一次,所以性能更好

试试这个:

List<Partner> items = await(from p in _context.Partners
                                    join d in _context.Devices
                                        on p.Id equals d.PartnerId
                                    group d by d.Partner /*relation property*/ into g
                                    select new Partner
                                    {
                                        Id = g.Key.Id,
                                        Name= g.Key.Name,
                                        DeviceCount=g.Count()
                                        // select other your properties here
                                    }).OrderBy(k => k.Name).ToListAsync();

但是,如果您想继续执行不推荐的操作,请尝试将 Partner 表放入内存中,然后从内存表中的这些表中选择数据。 像这样:

var partners=await _context.Partners.ToListAsync();

【讨论】:

  • 谢谢。这似乎是正确的轨道,有一些变化。我需要一个左连接而不是内部连接和一个生成 COUNT(d.Id) 而不是当前 COUNT(*) 的语法
【解决方案2】:

您要做的是内部加入它们,最好让 EF 处理它:

var partners =  from partner in _context.Partners
                join device in _context.Devices on partner.Id equals device.PartnerId into devices
                select new Partner()
                {
                    Id = partner.Id,
                    Name = partner.Name,
                    FiscalCode = partner.FiscalCode,
                    Licenses = partner.Licenses,
                    Erp = partner.Erp,
                    ErpName = partner.Erp == 1 ? "Erp 1" : "Erp 2",
                    Devices = devices
                };

【讨论】:

  • 感谢您的回答 Amirhossein,但我不想要加入,因为那样会增加行数。 devices 属性是一个整数,代表一个计数,而不是一个项目列表
猜你喜欢
  • 2020-04-28
  • 1970-01-01
  • 2020-03-27
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多