Entity Framework映射枚举:指定的值不是类型为“Edm.Int32”的实例 参数名称:值

9
我正在尝试将实体框架查询的结果返回到我的自定义dto类中,并且同时映射我的枚举TradeType。但是我遇到了以下错误:“指定的值不是 'Edm.Int32' 类型的实例 参数名:值”。你有解决方法或者变通方案吗?谢谢。
public IEnumerable<Trade> GetLiveTrades(string routeName)
{
    return _entities.Price.Where(p => p.StatusCode.Equals("A") && p.Period.PeriodYear <= DateTime.Now.Year+1 && p.Route.RouteCode.Equals(routeName)).
        Select(p => new Trade
                        {
                            Volume = (long) (p.Volume ?? 100), 
                            TradeType = (p.PriceTypeCode.Equals("O") ? TradeType.Seller : TradeType.Bidder),
                            Price = p.Price1,
                            TenorStartDate = p.Period.PeriodStartDate.Value,
                            TenorEndDate = p.Period.PeriodStartDate.Value,
                            TradeId = p.ID
                        }).ToList();
        }

public class Trade
{
    public long Volume { get; set; }
    public TradeType TradeType { get; set; }
    public double Price { get; set; }
    public DateTime TenorStartDate { get; set; }
    public DateTime TenorEndDate { get; set; }
    public Guid TradeId { get; set; }
}
3个回答

10

从 Entity Framework 投影(Select)中使用枚举是一个已知的问题。

_entities.Price.Where(p => p.StatusCode.Equals("A") &&
    p.Period.PeriodYear <= DateTime.Now.Year + 1 &&
    p.Route.RouteCode.Equals(routeName)).ToList() // ToList !
    .Select(p => new Trade ...

这个投影是由常规的Linq-to-Objects完成的,这是一个例行的工作。


编辑

作为晚期的想法,我想补充一点,当涉及到许多列的表时,仅仅使用ToList()可能会产生不良影响。它意味着传输到客户端的数据比必要的要多得多。在这种情况下,进行双重投影可能会很有用。首先,在查询提供程序的范围内将其投影到所接受的类型。然后,在切换到Linq-to-Objects (AsEnumerable)后,将其投影到最终类型:

_entities.Price.Where(p => p.StatusCode.Equals("A") &&
    p.Period.PeriodYear <= DateTime.Now.Year + 1 &&
    p.Route.RouteCode.Equals(routeName))
    .Select(p => new 
                {
                  Volume = (long) (p.Volume ?? 100), 
                  PriceTypeCode = p.PriceTypeCode,
                  Price = p.Price1,
                  TenorStartDate = p.Period.PeriodStartDate.Value,
                  TenorEndDate = p.Period.PeriodStartDate.Value,
                  TradeId = p.ID
                })
    .AsEnumerable()
    .Select(x => new Trade
                 {
                   Volume = x.Volume, 
                   TradeType = (x.PriceTypeCode.Equals("O") ? TradeType.Seller : TradeType.Bidder),
                   Price = x.Price1,
                   TenorStartDate = x.TenorStartDate,
                   TenorEndDate = x.TenorEndDate,
                   TradeId = x.ID
                 }).

谢谢,我通过更改我的DTO来解决了这个问题,它具有一个内部变量,存储PriceTypeCode的原始文本版本,然后我公开了一个属性,执行切换以返回正确的枚举。有点hacky,但它实现了所需的结果!:)感谢您的答案,我将在今后使用您的方法。 - Mantisimo
谢谢,这帮助我解决了问题。我将枚举转换为ToString()方法,并将其存储在查询外部的本地变量中,这对我很有帮助。 - John
嗨,@John。你的评论再次引起了我的注意,并促使我添加了一些想法。 - Gert Arnold
那么,AsEnumerable 允许您使用 LINQ 对象而不必立即执行到数据库中?太酷了。 - John

9
安装 .Net 4.5 看起来也可以解决该问题(您的项目仍然可以在 4.0 上)。
我在我们的演练服务器上遇到了这个问题(开发和测试服务器正常工作),并发现它没有安装 .Net 4.5。一旦我安装了 4.5,问题就得到了解决,而无需进行任何代码更改。

1
这是正确的,随着时间的推移,这将成为这个问题的答案。 - Gert Arnold
这怎么解决Windows XP机器上的问题? - TheButlerDidIt
@BitOriented,您是否认为在新版本的.Net中进行错误修复比编写自己的解决方法更不可取,因为旧的、不受支持的非服务器环境无法实现它? - Bradley Mountford
这个问题在我的本地机器上没有发生,但是出现在服务器上。在我的环境中(一切都取决于你的环境),我能够快速制作代码解决方法并部署一个新的DLL到DEV服务器,而这比要求其他人更新我无法控制的DEV服务器的.NET框架要快得多。耶! - AndyClaw

0

在尝试更新实体时,我遇到了这个错误。我添加了这个答案,因为当搜索该错误时,这个问题是最顶部的结果。对于更新操作,这是由于MySQL Connector中的一个bug导致的:

https://bugs.mysql.com/bug.php?id=44801

它似乎影响版本6.0.3及以下:

请参阅MySQL Connector for .Net 6.0.3的发行说明

它说明在此版本中不支持无符号整数EF。

最简单的修复方法(对我来说)是将该列更改为有符号而非无符号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接