AutoMapper > 使用可查询扩展和一些映射失败

AutoMapper > Using Queryable Extensions and some mapping fails

有什么方法可以使用 AutoMapper 映射这些 EntityFramework 实体吗?

我在尝试将 DateTime 对象(从我的 DBContext 实体)映射到我的 DTO 上的 TimeSpan 属性 时遇到错误。

这是个例外

----------- Exception #0 -----------
Type: System.NotSupportedException
Message: The specified type member 'TimeOfDay' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
Source: EntityFramework

它曾经在 ToList() 调用后映射实体时工作,但现在使用 AutoMapper 的 ProjectTo<> IQueryable 扩展,它显然试图将表达式转换为 SQL 可以的表达式明白了。

我的问题 - 是否可以将某些对象的映射配置为在服务器上执行查询后发生? (例如,在 ToList() 调用之后)

数据库实体上的 CloseTime 属性 是一个 DateTime 对象,但我们正在映射到一个 TimeSpan 对象

现在 - 我只是忽略了这样的属性

cfg.CreateMap<CustomerShipTo, ShipToBase>()
    .ForMember(desc => desc.OpenTime, src => src.Ignore())
    //.ForMember(desc => desc.OpenTime, src => src.CloseTime.TimeOfDay)
    .ReverseMap();

.ProjectTo() 需要能够最终映射到 SQL,因此与使用 .Map() 相比,映射可以做的事情存在限制。解决此类问题的方法是映射“原始”数据值,然后在 DTO 中使用翻译 属性。在您的情况下,因为这是一个数据类型转换,您可以将原始值称为“OpenDateTime”,通常如果我想使用相同的名称,我将使用前缀“Raw”来反映原始数据库值。 (即 RawOpenTime)

[Serializable]
public class ShipToBase
{
    // ...
    public DateTime OpenDateTime { get; set; }
    public Timespan OpenTime
    {
        get { OpenDateTime.TimeOfDay; }
        set { OpenDateTime = DateTime.MinValue().Add(value); } // Setter if needed.
    }
}

然后在映射中:

cfg.CreateMap<CustomerShipTo, ShipToBase>()
    .ForMember(desc => desc.OpenDateTime, src => src.OpenTime)
    .ForMember(desc => desc.OpenTime, src => src.Ignore())
    .ReverseMap();