Search code examples
entity-frameworkentity-framework-4enumsexpression

Entity framework mapping enum : The specified value is not an instance of type 'Edm.Int32' Parameter name: value


I'm trying to return the result of a entity framework query into my own dto class, at the same time as mapping my enum TradeType.

I'm getting the following error

The specified value is not an instance of type 'Edm.Int32' Parameter name: value

Any idea how to fix or a workaround?

Thanks

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

Solution

  • Enums in projections from Entity Framework projections (Select) is a know issue. If you do

    _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 ...
    

    the projection is done by regular linq-to-objects, which is a routine job.


    EDIT

    As a late afterthought I'd like to add that just a dumb ToList() can be detrimental when the table in question has many columns. It would mean that far more data is transferred to the client than necessary. In such cases it can be useful to do a double projection. First, within the scope of the query provider project to accepted types. Then, after switching to linq-to-objects (AsEnumerable) project to the final type:

    _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
                     }).