一尘不染

实体框架/ Linq EXpression从字符串转换为int

c#

我有一个这样的表达式:

var values = Enumerable.Range(1,2);

return message => message.Properties.Any(
    p => p.Key == name 
    && int.Parse(p.Value) >= values[0] 
    && int.Parse(p.Value) <= values[1]);

这样编译可以,但是当它命中数据库时会抛出异常 'LINQ to Entities does not recognize the method 'Int32 Parse(System.String)' method, and this method cannot be translated into a store expression '

如果我不进行分析并且将值设置为a string[],则不能在字符串上使用>=and <=运算符。

p.Value 是一个包含各种值的字符串,但是在这种情况下,它是 int

有没有一种方法可以查询数据库以执行这种之间的语句?


阅读 294

收藏
2020-05-19

共1个答案

一尘不染

正如其他人在评论中指出的那样,您必须解析该值的事实应该是一个危险信号,即您应该在数据库中使用其他数据类型。

幸运的是,有一种解决方法,可以强制查询由LINQ到对象而不是LINQ到实体执行。不幸的是,这意味着潜在地将大量数据读入内存

编辑

根据您的其他评论,“值”列中的值不能保证为数字。因此,您必须尝试将值转换为数字,然后根据该转换的失败/成功来处理事情:

return message
       .Properties
       .AsEnumerable()
       .Any(p => 
            {
                var val = 0;
                if(int.TryParse(p.Value, out val))
                {
                    return p.Key == name &&
                           val >= values[0] &&
                           val <= values[1])
                }
                else
                {
                    return false;
                }
           );

编辑2

您实际上可能能够在数据库中解决这个问题。我不确定这是否对您有用,但您可以试一下:

return message.Properties
              .Where(p => p.Key == name && SqlFunctions.IsNumeric(p.Value) > 0)
              .Any(p => Convert.ToInt32(p.Value) >= values[0] &&
                        Convert.ToInt32(p.Value) <= values[1]);
2020-05-19