LINQ表达式无法翻译-C#

时间:2020-07-07 13:21:33

标签: c# entity-framework linq entity-framework-6

我写了一个简单的查询(问题是我尝试在print(data[:10]) [ 0.00362846 0.00123409 0.00013711 -0.00029235 0.01515175 0.02780404 0.03610236 0.03410224 0.03887933 0.0307084 ] 下设置Address的时候):

ProductCode

上面的代码在此行中断:

 var query = _connectDBContext.Products
                            .Join(_context.CustomerRelations,
                                Product => Product.ForeignKeyId,
                                CustomerRelation => CustomerRelation.CompanyId,
                                (Product, CustomerRelation) => new { Product, CustomerRelation })
                            .Select(x => new ProductDto
                            {
                                Title = x.Product.Title,
                                ProductCode = x.Product.Code,
                                Address = Map(x.Product.Addresses.OrderBy(x=> x.CreatedDate).FirstOrDefault()),
                                //Address = new AddressDTO // THIS WORKS BUT LOOKS UGLY :(
                                //{
                                //    Address = x.Product.Addresses.OrderBy(x => x.CreatedDate).FirstOrDefault().Address,
                                //    Country = x.Product.Addresses.OrderBy(x => x.CreatedDate).FirstOrDefault().Country,
                                //    Zip = x.Product.Addresses.OrderBy(x => x.CreatedDate).FirstOrDefault().Zip,
                                //},
                               
                            })
                            .Where(x => x.Id == x.CustomerRelationId);

           // Rest of the code
        }

private AddressDTO Map(Address address)
{
    return new AddressDTO
    {
        Address = address.Address,
        Country = address.Country,
        Zip = address.Zip,

    };
}

它说linq无法翻译,并劝我重写查询。.

但是此注释的代码在这里几乎起作用了 ,因此,如果我删除了 Select 中的调用 Map 方法,并且取消了对此的注释, Select 中的代码可以正常运行,但是我想摆脱它-为每个道具写太多Address = Map(x.Product.Addresses.OrderBy(x=> x.CreatedDate).FirstOrDefault()), ,我想订购一次,此后我想使用它..但是不幸的是我不知道如何..:

OrderBy

预先感谢, 干杯

3 个答案:

答案 0 :(得分:5)

大概是Entity Framework将此代码转换为SQL,而您的自定义Map()方法对SQL来说是未知的。幸运的是,该方法的作用不大,因此您应该能够将其功能直接移至查询中。

您可以使用.Select()将集合投影为新类型(就像构建ProductDto时所做的一样)。

例如:

//...
Address = x.Product.Addresses.OrderBy(x=> x.CreatedDate)
                             .Select(x=> new AddressDTO
                             {
                                 Address = x.Address,
                                 Country = x.Country,
                                 Zip = x.Zip
                             })
                             .FirstOrDefault()
//...

答案 1 :(得分:0)

请参阅上述大卫的答案以解释为什么它不起作用。

要解决此问题,可以在映射之前调用.ToList(),以便在服务器上执行查询:

_connectDBContext.Products
  .Join(...)
  .Where(x => x.Id == x.CustomerRelationId)
  .ToList() // !!!
  .Select(x => new ProductDto
     {
        Title = x.Product.Title,
        ProductCode = x.Product.Code,
        Address = Map(x.Product.Addresses.OrderBy(x=> x.CreatedDate).FirstOrDefault()),
...
     });
                        

答案 2 :(得分:0)

您不能按原样调用Map函数,但可以对其进行一些修改以代替在Queryables上使用

var query = _connectDBContext.Products
                            .Join(_context.CustomerRelations,
                                Product => Product.ForeignKeyId,
                                CustomerRelation => CustomerRelation.CompanyId,
                                (Product, CustomerRelation) => new { Product, CustomerRelation })
                            .Select(x => new ProductDto
                            {
                                Title = x.Product.Title,
                                ProductCode = x.Product.Code,
                                Address = Map(x.Product.Addresses),
                               
                            })
                            .Where(x => x.Id == x.CustomerRelationId);

           // Rest of the code
        }

private AddressDTO Map(IQueryable<Address> addresses)
{
    return addresses.OrderBy(x => x.CreatedDate).Select(x => new AddressDTO
    {
        Address = address.Address,
        Country = address.Country,
        Zip = address.Zip
    }).FirstOrDefault();
}