我想解决 Linq To Entities 的结果选择中的“无法转换类型”问题

问题描述 投票:0回答:1

实体框架6

我有一个代表 Id 的类型:

public readonly record struct Id
{
    public Id(int intValue)
    {
        if (intValue <= 0)
            throw new InvalidIdException();

        IntValue = intValue;
    }


    public static explicit operator int(Id id) => id.IntValue;
    public static explicit operator Id(int id) => new(id);
    
    public int IntValue { get; }

    public override string ToString()
    {
        return IntValue.ToString();
    }
}

我还有一个扩展方法:

public static class IdHelper
{
    public static Id ToId(this int id)
    {
        return (Id) id;
    }
}

Order 有一个 DTO 类型:

public class Order {
  public Id OrderId {get;set;}
  public string OrderDesc {get;set;}
}

我想执行这样的查询:

var order = db.Orders.Select(x => new Order() { OrderId = x.order_id.ToId(), OrderDesc = x.order_desc });

它不起作用,因为 EF6 既不能翻译

ToId()
,也不能翻译
(Id)x.order_id
,也不能翻译
new Id(x.order_id)
。 我当然可以写:

var order = db.Orders.Select(x => new { x.order_id, x.order_desc }).ToList().Select(x => new Order() { OrderId = x.order_id.ToId(), OrderDesc = x.order_desc });

但是由于 DTO 有时可能很大,我想减少不必要的代码量和使用的内存(理想情况下我希望结果中有

List
而不是
WhereSelectListIterator

是否可以编写一些

ExpressionVisitor
或自定义
QueryProvider
来处理
ToId()
或在结果
Id
中显式转换为
Select

c# .net entity-framework entity-framework-6
1个回答
0
投票

您实际上不需要任何复杂的表达式,相反,您可以依靠 C# 运算符来为您完成这项工作。您已经定义了

explicit
运算符,这意味着您可以简单地执行以下操作:

var order = db.Orders
    .Select(x => new Order
    {
        OrderId = (Id)x.order_id,
        OrderDesc = x.order_desc
    });

或者,如果您将

explicit
更改为
implicit
,您可以完全放弃演员表:

var order = db.Orders
    .Select(x => new Order
    {
        OrderId = x.order_id,
        OrderDesc = x.order_desc
    });
© www.soinside.com 2019 - 2024. All rights reserved.