【发布时间】: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