【问题标题】:C# LINQ/EF throwing invalid cast on property with value conversionC# LINQ/EF 在具有值转换的属性上抛出无效强制转换
【发布时间】:2021-11-23 02:41:33
【问题描述】:

在我的数据库中,我有一个表对象

   public class Objects {

        [Key]
        public int ID { get; set; }

        blah blah blah

        public JCal CreationDate { get; set; }
}

属性CreationDate有一个Value Converter,如下:

var stdJCalConversion = new ValueConverter<JCal, double>(
    v => v.Timestamp,
    v => new JCal(v));

    modelBuilder
        .Entity<Objects>()
        .Property(e => e.CreationDate )
        .HasConversion(stdJCalConversion );

但是当我尝试运行一个简单的 where 子句时,如下所示:

fetch = await Objects.Where(c => c.CreationDate > someDouble).ToListAsync();

我收到以下异常:InvalidCastException: Invalid cast from 'System.Double' to 'x.Types.JCal'。

定义 JCal 的结构具有运算符重载,可以在 JCal 和双精度类型之间进行比较,但我怀疑 LINQ 不能像 EF 那样使用 ValueConversions。有什么办法可以让它工作,或者有什么解决方法吗?

【问题讨论】:

  • 你能做一个静态隐式运算符吗?
  • 在我的 JCal 结构中:public static implicit operator double(JCal jcal) =&gt; jcal.Timestamp; public static implicit operator JCal(double timestamp) =&gt; new(timestamp); 仍然得到无效的强制转换异常
  • EF 对用于比较的重载一无所知。所以这意味着它无法为您的查询创建 SQL。
  • 可能有点远,但在 SQL 中你也有 computed columns ,也许这可以执行从日期到双精度的转换,然后你只需与计算值进行比较。绝对不是答案,但可能值得研究
  • @JochemVanHespen 不是一个完美的解决方案,但这是个好主意。我在数据库中创建了一个 _Timestamp 记录,该记录评估为常规的 Timestamp 记录(在 asp net 中是 JCal 类型)并且有效。比我更喜欢的有点笨拙,但总比没有好

标签: c# asp.net entity-framework linq


【解决方案1】:

你也许可以使用一个表达式,像这样:

public static Expression<Func<Objects, bool>> IsHigherThanDouble(double someDouble)    
{        
   return (objects) => objects.CreationDate.Timestamp < someDouble;
}

那么你可以这样做:

fetch = await Objects.Where(IsHigherThanDouble(someDouble)).ToListAsync();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    • 2015-05-28
    相关资源
    最近更新 更多