【问题标题】:Concatenate int and string in LINQ to Entities在 LINQ to Entities 中连接 int 和 string
【发布时间】:2011-02-10 13:19:14
【问题描述】:

我正在使用以下代码:

from c in Country
 where c.IsActive.Equals(true)
 orderby c.CountryName
 select new
 {
     countryIDCode = c.CountryID + "|" + c.TwoDigitCode,
     countryName = c.CountryName
 }

但我在运行时遇到此错误:

无法将类型“System.Int32”转换为类型“System.Object”。 LINQ to Entities 仅支持转换实体数据模型基元类型。

CountryID 是 int 类型,TwoDigitCode 是 string 类型。

如何正确连接?

【问题讨论】:

    标签: linq entity-framework linq-to-entities


    【解决方案1】:

    使用 System.Data.Objects.SqlClient.SqlFunctions.StringConvert

     from c in Country
     where c.IsActive.Equals(true)
     orderby c.CountryName
     select new
     {
         countryIDCode = SqlFunctions.StringConvert((double)c.CountryID) 
                         + "|" + c.TwoDigitCode,
         countryName = c.CountryName
     }
    

    【讨论】:

    • 我不太确定。从我的角度来看,数据库类型的行为总是有点奇怪,而 SqlFunctions 实用程序是我用来解决问题的工具,例如发布的问题。与 ToList 转换等不太明显的解决方案相比,我更喜欢这种方法,因为它明确向任何维护你的代码的人显示你正在做什么。
    • 我相信这应该是公认的答案,因为它解决了问题而不会像 Nicholas Murray 的答案那样引入性能损失(尽管它确实说 ...and is a small dataset)。
    • 在 EF6 中,这已移至 System.Data.Entity.SqlServer.SqlFunctions.StringConvert stackoverflow.com/questions/19733085/…
    【解决方案2】:

    如果此错误阻止您继续进行并且是一个小型数据集,您可以通过枚举查询(调用 ToList)来丰富您从数据库中的检索。从那时起,您的操作将针对内存中的对象,您可能不会遇到收到的错误。

    var countries = (from c in Country
    where c.IsActive.Equals(true)
    orderby c.CountryName
    select c).ToList();
    
    
    var countryCodes = (from c in countries
    where c.IsActive.Equals(true)
        orderby c.CountryName
        select new
        {
            countryIDCode = c.CountryID + "|" + c.TwoDigitCode,
            countryName = c.CountryName
        });
    

    【讨论】:

    • 我认为这个答案已经过时并且总体上是不好的做法。这是一个快速的'n'dirty修复,它现在有效,但稍后会咬你(例如,当你当前的小数据集突然增长,或者客户决定他想要在另一个更大的数据集上完全相同的东西时)。请参阅直接使用 db 函数的 flyfisher1952 的答案,使其成为比此答案更好的解决问题的方法。
    【解决方案3】:

    本主题包含可转换为命令树规范函数并在服务器上执行的 CLR 方法列表:

    MSDN

    对于不在此列表中的 CLR 方法,您必须使用 .AsEnumerable() 将结果下拉到客户端并执行 LINQ to Objects 查询。

    【讨论】:

      【解决方案4】:

      这是旧版本实体框架的限制。我认为使用 v4 可以解决。对于您的版本,解决方法是将结果转换为可枚举:

      from a in 
      (from c in Country
      where c.IsActive.Equals(true)
      orderby c.CountryName).AsEnumerable()
      select new
      {
          countryIDCode = a.CountryID + "|" + a.TwoDigitCode,
          countryName = a.CountryName
      }
      

      【讨论】:

      • 我正在尝试您的方法,但出现编译时错误:查询正文必须以 select 子句或 group 子句结尾。
      • 您显示的查询将在 EF 1 和 4 中或多或少地正常工作。
      • 是的,但我不确定您是否仍需要在 v4 中使用此解决方法或限制已解决。
      • 使用 EF4 并得到同样的错误。找到您的答案并使用 AsEnumerable() 解决它。现在真的更喜欢 L2S 而不是 EF4....
      【解决方案5】:

      int 到字符串转换没有mapping to a Canonical Function

      所以只需在 2 个不同的列 中返回 IntString,然后在使用 AsEnumerable 方法后在 .NET 中将它们连接起来:

      var cListTemp = from c in Country
          where c.IsActive.Equals(true)
          orderby c.CountryName
          select new
          {
              countryID = c.CountryID,
              twoDigitCode = c.TwoDigitCode,
              countryName = c.CountryName
          };
      
      var cList = cListTemp.AsEnumerable().Select(c => new {
          countryIDCode = c.countryID + "|" + c.twoDigitCode,
          countryName = c.countryName
      });
      

      【讨论】:

        【解决方案6】:

        我能够使用以下代码连接字符串:

        l.StateName + " " + SqlFunctions.StringConvert( (double?)l.Zip ).Trim()
        

        似乎只是SqlFunctions.StringConvert( (double?)l.Zip ) 就足够了,但是生成的字符串在左侧有一堆填充,这导致字符串比较不匹配。事实证明,Trim() 可以减少多余的部分。我相信SqlFunctions.StringConvert( (double?)l.Zip ).Trim()实际上变成了SQL:LTrim(RTrim(STR(Zip)))

        【讨论】:

          【解决方案7】:

          使用c.CountryId.ToString() 获取您的 CountryId 的字符串表示形式并将其连接到您的 TwoDigitCode 字段:

          from c in Country
           where c.IsActive.Equals(true)
           orderby c.CountryName
           select new
           {
               countryIDCode = c.CountryID.ToString() + "|" + c.TwoDigitCode,
               countryName = c.CountryName
           }
          

          我希望您的错误实际上是编译器错误(想不出编译器会允许此查询的任何方式。不过我不确定它如何知道 Linq to Entities 部分)。

          【讨论】:

          • 不,这个不能用。在这种情况下出现以下错误:LINQ to Entities 无法识别方法“System.String ToString()”方法,并且该方法无法转换为存储表达式。
          • .ToString() 和 .Format() 无法在 sql 客户端上执行,因此会出现运行时错误。
          • 在 L2S 中运行良好,您可能正在使用 EF。不过,没有理由不赞成,你应该更明确。
          【解决方案8】:

          如果您需要将它们作为字符串连接在一起,您可以使用String.Format 方法:

          countryIDCode = String.Format("{0}|{1}", c.CountryID, c.TwoDigitCode)
          

          【讨论】:

          • 否,它给出运行时错误:LINQ to Entities 无法识别方法 'System.String Format(System.String, System.Object, System.Object)' 方法,并且该方法无法翻译成商店表达式。
          • .ToString() 和 .Format() 无法在 sql 客户端上执行,因此会出现运行时错误。
          • 嗯,问题是“在 LINQ 中连接 int 和字符串”而不是在 Linq To SQL 等中。OP 应该更清楚。 LINQ != SQL
          • OP 也错误地标记了该问题。 +1 回答 OP 的问题,即使这不是他真正想要的问题。
          猜你喜欢
          • 1970-01-01
          • 2011-07-31
          • 2013-09-09
          • 2012-01-15
          • 1970-01-01
          • 1970-01-01
          • 2011-09-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多