C# 由于字符串比较,文档编号计算不正确

C# 由于字符串比较,文档编号计算不正确,c#,.net,string,linq,C#,.net,String,Linq,我有一个要评估的文件编号列表。这个列表非常大,我不希望将所有文档编号转换为int,因为它们也可以包含字母。这是一个数字的示例列表 1070 1071 1072 1073 1074 1075 1076 1077 1078 CO1089 CO1099 CO2000 这些数字包含在C#中的对象中,我运行Linq返回一个范围内的对象列表。这是我的linq代码 results = from row in MyObjectList.AsQueryable<MyObject>()

我有一个要评估的文件编号列表。这个列表非常大,我不希望将所有文档编号转换为int,因为它们也可以包含字母。这是一个数字的示例列表

1070
1071
1072
1073
1074
1075
1076
1077
1078
CO1089
CO1099
CO2000
这些数字包含在C#中的对象中,我运行Linq返回一个范围内的对象列表。这是我的linq代码

results = from row in MyObjectList.AsQueryable<MyObject>()
          where String.Compare(row.Header.DocNumber, _sDocumentStartNumber) >= 0 
          && String.Compare(row.Header.DocNumber, _sDocumentEndNumber) <= 0
          select row;
results=来自MyObjectList.AsQueryable()中的行
其中String.Compare(row.Header.DocNumber,_sDocumentStartNumber)>=0

&&String.Compare(row.Header.DocNumber,_sDocumentEndNumber)创建自己的比较器,比如说
documentnumberwhithinrangecomparer

public class DocumentNumberWithinRangeComparer
{
    public int? RangeFrom { get; set; }
    public int? RangeTo { get; set; }

    public DocumentNumberWithinRangeComparer(int? from, int? to)
    {
        RangeFrom = from;
        RangeTo = to;
    }

    public bool IncludeInResults(MyObject obj)
    {
        if (!RangeTo.HasValue || !RangeFrom.HasValue)
            return true;

        int docnumber;
        if (!Int32.TryParse(obj.Header.DocNumber, out docnumber))
            return false;

        return docnumber >= RangeFrom.Value && docnumber <= RangeTo.Value;
    }
}

设置此词典需要一些额外的时间,但如果您多次查询同一文档集,则会得到回报。

当您获得范围时,请在起始编号上加空格,使其长度与结束编号相同。所以在你的例子中,你的结束数字是“10000”。因此,请将起始数字设为“_1”(即4个空格,然后是1)

比较时,请在比较前左键填充文档编号。因此:

string paddedStart = _sDocumentStartNumber.PadLeft(_sDocumentEndNumber.Length);
string padded;
results = from row in MyObjectList.AsQueryable<MyObject>()
      let padded = row.Header.DocNumber.PadLeft(paddedStart.Length)
      where String.Compare(padded, paddedStart) >= 0 
          && String.Compare(padded, _sDocumentEndNumber) <= 0
      select row;
string paddedStart=\u sDocumentStartNumber.PadLeft(\u sDocumentEndNumber.Length);
线垫;
结果=来自MyObjectList.AsQueryable()中的行
让padded=row.Header.DocNumber.PadLeft(paddedStart.Length)
其中String.Compare(padded,paddedStart)>=0

&&比较(填充,_sDocumentEndNumber)“非常大”有多大?我建议先让代码以最简单的方式工作,然后测试它的性能,而不是假设这会太慢。(还有,为什么要使用
AsQueryable
?)并且“CO2000”应该被视为2000,还是不被视为一个值?在选择范围时是否要包括“字母数字”文档编号?我建议您创建自己的
I比较程序
,而不是使用
字符串。比较
。在这种情况下,不会返回带有字母字符的文档编号。我之所以使用AsQueryable,是因为“MyObject”实际上是我用来与另一个产品交互的SDK对象列表。大量的对象很容易超过100000个。我没有硬性数字,因为这取决于用户在外部包中创建了多少对象。我希望对列表进行预处理。那会让事情变得容易得多。也许今年晚些时候intuit的IPP的v3版本会包括额外的过滤,这样我就不必做所有这些了。谢谢你的回复。我将用我们的示例数据运行一些测试,看看它们与性能的比较。我最终使用了您建议的comparer类。我没有使用字典路由,因为我只会传递一次数据(尽管我在这个程序中都有字典,用于重复使用的数据。对云的调用越少越好)。比较器方法对性能没有任何明显的影响,当用户只使用数字搜索时,它实际上可能提高了性能,因为我在一个检查中添加了数字以简化处理。非常感谢。
var dictionary = new Dictionary<string, int>(); // Fill this...
var results = from row in MyObjectList.AsQueryable<MyObject>()
              where dictionary[row.Header.DocNumber] >= _sDocumentStartNumber &&
                    dictionary[row.Header.DocNumber] <= _sDocumentEndNumber 
              select row;
string paddedStart = _sDocumentStartNumber.PadLeft(_sDocumentEndNumber.Length);
string padded;
results = from row in MyObjectList.AsQueryable<MyObject>()
      let padded = row.Header.DocNumber.PadLeft(paddedStart.Length)
      where String.Compare(padded, paddedStart) >= 0 
          && String.Compare(padded, _sDocumentEndNumber) <= 0
      select row;