.net 我想解决“无法强制转换类型”的结果选择的链接到实体

enyaitl3  于 12个月前  发布在  .NET
关注(0)|答案(1)|浏览(104)

Entity Framework 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;
    }
}

订单有一个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()或在结果Select中显式转换为Id

qhhrdooz

qhhrdooz1#

在这里,你真的不需要任何复杂的表达式,相反,你可以依靠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
    });

相关问题