【问题标题】:Int.Parse in Linq ExpressionLinq 表达式中的 Int.Parse
【发布时间】:2012-08-20 12:58:44
【问题描述】:

我有以下 LINQ 表达式。我想计算 nvarchar 字段中数值的总和。我正在使用以下代码来执行此操作,但是当我尝试运行此代码时出现错误。

var m = new MaterialModelContainer();

var list = 
    (from x in
        (
            from inv in m.INVs
            join l in m.LIBs on inv.MESC equals l.MESC
            join o in m.OUTs on inv.MESC equals o.MESC
            join t in m.TRANs on inv.MESC equals t.MESC
            where t.TYPE == "60"
            select new
            {
                l.MESC,
                l.LINE_NO,
                l.UNIT_LINE,
                Description = l.DES + " " + l.PART_NO,
                inv.NEW_QTY,
                o.PJ,
                o.DATE,
                o.QTY,
                o.QTY_REC,
                TranQty = t.QTY,
                tranDate = t.DATE
            }
        )
        group x by
            new
            {
                x.MESC,
                x.LINE_NO,
                x.UNIT_LINE,
                x.Description,
                x.NEW_QTY,
                x.PJ,
                x.DATE,
                x.QTY,
                x.QTY_REC
            }
        into g
        select new
        {
            QTY_Consum_1 = g.Where(c => int.Parse(c.tranDate) >= cuDate && int.Parse(c.tranDate) <= endDate).Sum(d => int.Parse(d.TranQty))
        }
    ).ToList();

错误说明:

LINQ to Entities 无法识别方法 'Int32 Parse(System.String)' 方法,并且该方法无法翻译 变成商店表达式

我怎样才能解决这个问题并写出比这更好的代码?

我把代码改成这样:

select new
{
    QTY_Consum_1 = g.Where(c => SqlFunctions.StringConvert(c.tranDate) >= cuDate && SqlFunctions.StringConvert(c.tranDate) <= endDate).Sum(d => SqlFunctions.StringConvert(d.TranQty)),
   g.Key.MESC
}
).ToList();

但收到此错误:

【问题讨论】:

标签: c# linq entity-framework


【解决方案1】:

EF 5:

使用Convert.ToInt32 代替int.Pasrse。 Entity Framework 将在 SQL 中生成正确的CAST 函数。

EF 6:

简答:

youEntity.Where(c=>SqlFunctions.StringConvert((decimal?)c.INTFIELD).Trim() == STRINGVALUE)

长答案:

在 EF 6 中,您必须使用 SqlFunctions.StringConvert 将数值转换为字符串。但它有一个问题。它会在结果中添加不必要的空格。所以比较会失败。这就是我将Trim() 放在那里的原因。我已经用 EF 6.1.1 对其进行了测试。

【讨论】:

  • 有人可以确认吗?对我来说,这不起作用(EF 6.1.0)
  • 问题是关于将字符串解析为int,反之亦然。
【解决方案2】:

Entity Framework 无法将这种类型的转换转换为 SQL。

您是否有机会更改数据结构以使用正确的数据类型,例如实际的DateTime 类型?对于大数据量,这样的转换会影响性能。

我建议要么更改数据模型类型以避免这些转换,要么如果数据量总是很小,然后先获取数据,然后再使用 Linq to Objects。 p>

【讨论】:

    【解决方案3】:

    在 where 子句中,您不能调用 int.Parse。实体框架不知道如何将其转换为 SQL。考虑修改您的Where

    【讨论】:

      【解决方案4】:

      将您的所有int.Parse 替换为SqlFunctions.StringConvert(variable)。没有将 String 转换为 Int 的函数。您应该尝试做相反的事情并使用 StringConvert 将您的 Int 转换为 String。

      SqlFunctions 实用程序将能够在 SQL 命令中转换命令。

      【讨论】:

      • 这不是相反,将数字转换为字符串吗?
      • 我将 int.parse 更改为 SqlFunctions.StringConvert(variable) 但我收到错误,我编辑问题。请帮我。谢谢
      • @PabloRomea 你是对的。我错过了!但它似乎没有将字符串转换为 int 的功能。现在,我将通过使用 StringConvert 将 Int 转换为 String 来反转子句
      • @M.B 传递给 StringConvert 的值必须是 DoubleDecimal。您需要将变量转换为其中一种类型。
      • 数据库不属于我,我只能对它运行查询。
      【解决方案5】:

      您不能在 where 中使用 int.parse。您可以像这样重写您的查询:

      var list = (from x in
                      (
                          from inv in m.INVs
                          join l in m.LIBs on inv.MESC equals l.MESC
                          join o in m.OUTs on inv.MESC equals o.MESC
                          join t in m.TRANs on inv.MESC equals t.MESC
                          where t.TYPE == "60" && t.QTY!=""
                          select new
                             {
                                 l.MESC,
                                 l.LINE_NO,
                                 l.UNIT_LINE,
                                 Description = l.DES + " " + l.PART_NO,
                                 inv.NEW_QTY,
                                 o.PJ,
                                 o.DATE,
                                 o.QTY,
                                 o.QTY_REC,
                                 TranQty = t.QTY,
                                 tranDate = t.DATE
      
                            }
                      ).ToList()
                  group x by
                      new
                          {
                              x.MESC,
                              x.LINE_NO,
                              x.UNIT_LINE,
                              x.Description,
                              x.NEW_QTY,
                              x.PJ,
                              x.DATE,
                              x.QTY,
                              x.QTY_REC
                          }
                  into g
                  select new
                      {
                          QTY_Consum_1 = g.Where(c => int.Parse(c.tranDate) >= cuDate && int.Parse(c.tranDate) <= endDate).Sum(d => int.Parse(d.TranQty)),
                          g.Key.MESC
                      }
                 ).ToList();
      

      调用.ToList()方法,然后使用int.Parse(variable)

      祝你有美好的一天。

      【讨论】:

      • 但是where子句会在数据库外执行!
      • 最好使用AsEnumerable 以避免创建中间列表。
      【解决方案6】:

      有一个糟糕的数据库,我无法编辑,但必须使用它。

      我在 Linq-To-Sql 中使用它,它可以工作。

      首先将字符串转换为对象,然后将其转换为 int。

       from s in db.Students
       select new
       {
           s.Name,
           s.Surname,
           Birthday = new DateTime((int)(object)(s.dateStr.Substring(0, 4)),
                                   (int)(object)(s.dateStr.Substring(4, 2)),
                                   (int)(object)(s.dateStr.Substring(6, 2))),
       }
      

      【讨论】:

        【解决方案7】:

        当您需要确保可以在 LINQ to Entities 中使用 CLR 方法时,您最好查阅以下来源:https://msdn.microsoft.com/en-us/library/vstudio/dd456828(v=vs.100).aspx

        阅读速度不快,需要时间,但这是您问题的答案(还有更多类似的问题)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-03-25
          • 1970-01-01
          • 1970-01-01
          • 2020-08-11
          • 2022-12-22
          • 2018-09-29
          • 2011-11-22
          相关资源
          最近更新 更多