无法转换LINQ表达式以可以转换的形式重写查询,或切换到客户端计算

rmbxnbpk  于 2023-02-06  发布在  其他
关注(0)|答案(2)|浏览(97)

我有C#应用程序,我写了下面的LINQ表达式。

var invoices = await this.Context
    .Set<InvoiceItem>().Where(x => x.Status == "Created")
    .Where(query.Filter)
    .OrderBy(query.Sort)
    .Paginate(pageInfo)
    .ToListAsync();

foreach (var item in invoices)
{
    item.ServiceEndDate = this.Context.InvoiceLineItems
        .FirstOrDefault(x => x.InvoiceId == item.Id) != null 
            ? this.Context.InvoiceLineItems.FirstOrDefault(x => x.InvoiceId == item.Id).ServiceEndDate 
            : null;
}
return invoices;

每当执行此表达式时,我都会得到以下错误
LINQ表达式“DbSet()”\r\n。其中(i =〉i.业务ID == __ef_filter__BusinessId_0||__ef_filter__IsMedCompliUser_1)\r\n .其中(i =〉i.状态==“已创建”)\r\n .其中(i =〉i.IsActive == __Value_0)\r\n .排序依据(i =〉(对象)i.服务结束日期.值)'无法转换。附加信息:转换实体类型“InvoiceItem”上的成员“ServiceEndDate”失败。当取消Map指定的成员时,通常会发生这种情况。\r\n转换实体类型“InvoiceItem”上的成员“ServiceEndDate”失败。当取消Map指定的成员时,通常会发生这种情况。请以可以转换的形式重写查询,或者通过插入对“AsEnumerable”、“AsAsyncEnumerable”、"AsyncEnumerable“的调用,显式切换到客户端计算。
型号部件:

public class InvoiceItem : IHasTenant
{
    public long Id { get; set; }
    public long BusinessId { get; set; }

    public bool IsActive { get; set; }

    public DateTime? InvoiceDate { get; set; }
    public DateTime? DateOfService { get; set; }
    [NotMapped]
    public DateTime? ServiceEndDate { get; set; }

页面信息:

public class PageInfo : MedCompli.Common.Contracts.PageInfo
{
}

public static class PageInfoExtensions
{
    public static bool IsPageNumberValid(this PageInfo pageInfo)
    {
        return MedCompli.Common.Extensions.PageInfoExtensions.IsPageNumberValid(pageInfo);
    }

    public static bool IsPageSizeValid(this PageInfo pageInfo)
    {
        return MedCompli.Common.Extensions.PageInfoExtensions.IsPageSizeValid(pageInfo);
    }
}

质询:

namespace MedCompli.Core.Contracts
{
    //
    // Summary:
    //     Object that contains sorting and filtering parameters for an Entity Framework
    //     query.
    public class Query
    {
        public Query();

        //
        // Summary:
        //     Filtering parameters.
        [FromQuery(Name = "q")]
        [JsonProperty("q")]
        public QueryFilter Filter { get; set; }
        //
        // Summary:
        //     Sorting parameters.
        [FromQuery(Name = "s")]
        [JsonProperty("s")]
        public IDictionary<string, SortOperator> Sort { get; set; }

        public virtual QueryFilter ConvertFilterProperties(IMapper mapper);
        public virtual IDictionary<string, SortOperator> ConvertSortProperties(IMapper mapper);
    }
}
n8ghc7c1

n8ghc7c11#

错误显示:
转换实体类型"InvoiceItem"上的成员"ServiceEndDate"失败。
表达式包含OrderBy(i => (object)i.ServiceEndDate.Value)所以提供者不知道如何Map这个条件,因为属性没有被Map。
您需要Map此属性或不在查询(条件、排序等)中使用

x4shl7ld

x4shl7ld2#

如果要使未Map的属性可翻译,EF Core应该知道此属性如何Map到数据库。在这种情况下,必须使用附加属性ServiceEndDate手动投影所有属性

var invoices = await this.Context
    .Set<InvoiceItem>().Where(x => x.Status == "Created")
    .Selec(x => new InvoiceItem
    {
        Id = x.Id,
        BusinessId = x.BusinessId,
        IsActive = x.IsActive,
        InvoiceDate = x.InvoiceDate,
        DateOfService = x.DateOfService,
        ServiceEndDate = x.ServiceEndDate,

        // other propeties

        ServiceEndDate = (DateTime?)this.Context.InvoiceLineItems
            .Where(li => li.InvoiceId == item.Id)
            .Select(li => li.ServiceEndDate)
            .FirstOrDefault()
    })
    .Where(query.Filter)
    .OrderBy(query.Sort)
    .Paginate(pageInfo)
    .ToListAsync();

注意,如果没有OrderByFirstOrDefault就没有意义。

相关问题