【问题标题】:Unable to cast System.Double to System.Object. LINQ to Entities only supports casting EDM primitive or enumeration types无法将 System.Double 强制转换为 System.Object。 LINQ to Entities 仅支持转换 EDM 基元或枚举类型
【发布时间】:2018-07-13 22:04:26
【问题描述】:

您好,我正在尝试将Nullable<Double> 属性列表转换为object[][] 属性,如下所示。

WeibullLinearRegression.LinearRegressionPoints = await context.WeibullLinearRegressionPoints.Where(x => x.WeibullFilterDetailsId == filterId).Select(x => new object[] 
   { x.XCoordinate !=null? (double)x.XCoordinate : default(double), 
     x.YCoordinate != null ? (double)x.YCoordinate: default(double)
   }
).ToArrayAsync(token);

我尝试了所有可能的组合,使用默认值等仍然会引发如下错误。不知道为什么会这样。

Unable to cast System.Double to System.Object. LINQ to Entities only supports casting EDM primitive or enumeration types.

非常感谢您的帮助!

更新

正如其他一些帖子建议尝试使用泛型数组一样,仍然没有用! :(

WeibullLinearRegression.LinearRegressionPoints = await context.WeibullLinearRegressionPoints.Where(x => x.WeibullFilterDetailsId == filterId).Select(x => **new []** 
   { x.XCoordinate !=null? (double)x.XCoordinate : default(double), 
     x.YCoordinate != null ? (double)x.YCoordinate: default(double)
   }
).ToArrayAsync(token);

【问题讨论】:

  • 是否有任何特殊原因需要数据库来执行 Select 子句(因为它真的不能,这就是您看到错误的原因)?如果没有,只需将 Select 放在 ToArrayAsync 之后,然后再放一个 ToArray。然后 Select 将在内存中作为原生 C# 执行,而不是试图变成一些复杂的 SQL 查询。
  • 就是这样!谢谢!

标签: c# list linq lambda


【解决方案1】:

我对你想要做什么特别是对双维数组有点迷茫。而且,我只是用一个对象列表来做这件事,而不是用 EF 和所有这些。所以我创建了这种类型(抱歉,属性名称更短):

public class DataClass
{
    public int Id { get; set; }
    public double? X { get; set; }
    public double? Y { get; set; }
    public DataClass (int id, double? x, double? y)
    {
        Id = id;
        X = x;
        Y = y;
    }
}

然后我填写了他们的清单:

var data = new List<DataClass>
{
    new DataClass(1, 1.0, 2.0),
    new DataClass(2, 2.0, 3.0),
    new DataClass(3, 3.0, null),
};

然后我做了这个查询(使用 Linq 语法,而不是扩展方法):

 var result = from d in data
     where d.Id > 1
     select new[]
     {
         new
         {
             X = d.X ?? default(double),
             Y = d.Y ?? default(double)
         }
     };
 var array = result.ToArray();

结果是一个匿名类型的二维数组,但数组是[2][1]。在监视窗口中,它看起来像(抱歉格式化,但我不知道如何使它看起来更好):

-       array   {<>f__AnonymousType0<double, double>[2][]}  <>f__AnonymousType0<double, double>[][]
-       [0] {<>f__AnonymousType0<double, double>[1]}    <>f__AnonymousType0<double, double>[]
+       [0] { X = 2, Y = 3 }    <Anonymous Type>
-       [1] {<>f__AnonymousType0<double, double>[1]}    <>f__AnonymousType0<double, double>[]
+       [0] { X = 3, Y = 0 }    <Anonymous Type>

这就是你想要做的吗?

好的,我多看了你的原始帖子,发现你想要一个数组 [N][2],其中两个成员是 X 和 Y 元素。所以我尝试了这个:

var result2 = from d in data
    where d.Id > 1
    select new[]
    {
        d.X ?? default(double),
        d.Y ?? default(double)
    };
var array2 = result2.ToArray();

最后在观察窗口中看到了这个:

-       array2  {double[2][]}   double[][]
-       [0] {double[2]} double[]
    [0] 2   double
    [1] 3   double
-       [1] {double[2]} double[]
    [0] 3   double
    [1] 0   double

我认为这可能更接近。它应该可以与 EF 一起工作(tm),但我还没有尝试过。

【讨论】:

  • EF 不能“正常工作”,这是真正的问题。并非 C# 中可表达的所有内容都可以转换为有效的 SQL,这就是这里的问题。
  • 因此斜体字“应该工作”。那时,你需要玩一些游戏——消耗内存的游戏。从数据库中拉取集合(使用 ToList 或其他),然后在第二遍中,塑造成您想要的形状。您可能能够以 EF 风格完成部分工作,然后使用 foreach 完成它。对不起 - 我试过了。获取 List 是否适用于 EF(使用 ToList 而不是 ToArray)?
  • 谢谢 DaveM 和 Flydog57。你们俩都指出的真正问题是由于数据库上的 Select 查询,SQL 查询过于复杂。转换 toListAsync 然后选择它完美地工作!经验教训 - 保持对 DB 的查询简单,然后稍后使用 Linq 调整结果! 谢谢大家。
  • 这是有效的查询! (await context.WeibullLinearRegressionPoints.Where(x =&gt; x.WeibullFilterDetailsId == filterId).ToListAsync(token)).Select(x =&gt; new object[] { x.XCoordinate, x.YCoordinate }).ToArray()
【解决方案2】:

如上面的 cmets 所述。问题是对数据库的查询很复杂。

解决方案 - 转换为 ToList,然后调整结果。

感谢@DaveM 和@Flydog57

以下是有效的查询。

(await context.WeibullLinearRegressionPoints.Where(x =&gt; x.WeibullFilterDetailsId == filterId).ToListAsync(token)).Select(x =&gt; new object[] { x.XCoordinate, x.YCoordinate }).ToArray()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    相关资源
    最近更新 更多