【问题标题】:Leading zeroes, wierd behaviour前导零,奇怪的行为
【发布时间】:2017-04-28 07:01:54
【问题描述】:

所以最初的问题与 Linq-to-SQL 有关,但我真的认为它归结为 Linq 如何处理字符串中的前导零。在我最初的解决方案中,当我遇到这种奇怪的前导零行为时,我尝试使用 Linq 和实体框架 (*) 复制 SQL 的 BETWEEN 子句,请在此处查看示例:

myObj 类

public class myObj
{
   public string A, B, C;
   public string Name;
   public myObj(string name, string a, string b, string c)
   {
      Name = name;
      A = a;
      B = b;
      C = c;
   }
}

制作一个包含三个 myObjs 的列表

List<myObj> myList = new List<myObj>();

启动它们并给它们命名和值。然后将它们添加到列表中。

myObj moA = new myObj("noLeadingZero", "1000", "2000", "3000");
myObj moB = new myObj("noLeadingZero", "3000", "4000", "5000");

在对象“LeadingZero”上,我会给最后一个值加上前导零。

myObj moC = new myObj("LeadingZero", "5500", "6000", "0300");

然后将它们添加到列表中:

myList.Add(moA);
myList.Add(moB);
myList.Add(moC);

现在!

当尝试使用 Linq 获取区间“-1”到“9999”内的所有对象时,我只得到了三个对象中的两个。这不可能! “LeadingZero”对象应该在结果中,因为“0300”高于 -1 低于 9999。

var match = (from lst in myList where
             lst.A.CompareTo("-1") >= 0 &&
             lst.A.CompareTo("9999") <= 0 &&

             lst.B.CompareTo("-1") >= 0 &&
             lst.B.CompareTo("9999") <= 0 &&

             lst.C.CompareTo("-1") >= 0 &&
             lst.C.CompareTo("9999") <= 0
             select lst).ToList();

如果我删除最后一部分 (lst.C.CompareTo("-1") >= 0 && lst.C.CompareTo("9999") ) 或者如果我更改“-1”到“0”我会得到所有三个对象。但是为什么 Linq 会这样呢?


(*) 在我原来的解决方案中,“-1”值被保存而不是 null。

【问题讨论】:

  • 您是在比较 strings 而不是 numbers。所以你是按字母顺序比较的。
  • 这不是 Linq 的奇怪行为,而是查询中字符串比较返回的结果。
  • @HansKesting 事实上,我知道我比较的是字符串而不是数字。但是比较不应该仍然产生“0300”吗?我的意思是,在原始解决方案(使用 SQL+EF)中,值始终保存为字符串,并且某些值可以包含前导零(原始解决方案用于会计)。
  • @Will_Bachman:比较“Hello”和“Hella”的结果是什么? “123456789”到“123456788”? “123”到“onetwothree”?用数字表示字符串的差异是非常难以理解的。您获得“0300”的期望取决于您巧合使用具有数字字符的字符串。但是对于一台计算机来说,“123”、“apl”和“456”都是一样的不同。它看不到你所做的模式,因为模式可能纯属巧合。
  • 没有区间“-1”到“9999”,除非您期望“-1”介于“1”和“112”之间。 C# 中的默认字符串比较是忽略连字符,因为它旨在用于按字母顺序排列单词,而不是比较数字。

标签: c# entity-framework linq


【解决方案1】:

进行整数比较或将 A、B 和 C 声明为 int

var match = (from lst in myList where
         Convert.ToInt32(lst.A).CompareTo(-1) >= 0 &&
         Convert.ToInt32(lst.A).CompareTo(9999) <= 0 &&

         Convert.ToInt32(lst.B).CompareTo(-1) >= 0 &&
         Convert.ToInt32(lst.B).CompareTo(9999) <= 0 &&

         Convert.ToInt32(lst.C).CompareTo(-1) >= 0 &&
         Convert.ToInt32(lst.C).CompareTo(9999) <= 0
         select lst).ToList();

【讨论】:

  • 是的,当然。但是如果一个值是这样的“ABAB”呢: myObj moB = new myObj("WithLetters", "3000", "ABAB", "5000"); ?
  • 我认为即使是你也不明白你想做什么。您不能真正实现字符串和整数比较,可以吗?非常有趣的反对票很可能是因为您不清楚您想要实现什么。
猜你喜欢
  • 2013-02-05
  • 2015-11-13
  • 1970-01-01
  • 2020-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 2023-03-09
相关资源
最近更新 更多