正则表达式替换以帮助LINQ中的Orderby

时间:2008-12-22 17:47:34

标签: c# regex linq linq-to-sql

我正在使用LINQ to SQL从数据库中提取记录,按字符串字段对它们进行排序,然后对它们执行其他一些工作。不幸的是,我正在排序的名称字段来自数据库,如此

Name
ADAPT1
ADAPT10
ADAPT11
...
ADAPT2
ADAPT3

我想按数字顺序对Name字段进行排序。现在我正在使用Regex对象将“ADAPT1”替换为“ADAPT01”等。然后我使用另一个LINQ查询再次对记录进行排序。我的代码就像

    var adaptationsUnsorted = from aun in dbContext.Adaptations
                              where aun.EventID == iep.EventID
                              select new Adaptation
                              {
                                  StudentID = aun.StudentID,
                                  EventID = aun.EventID,
                                  Name = Regex.Replace(aun.Name,
                                     @"ADAPT([0-9])$", @"ADAPT0$1"),
                                  Value = aun.Value
                              };

    var adaptationsSorted = from ast in adaptationsUnsorted
                            orderby ast.Name
                            select ast;

    foreach(Adaptation adaptation in adaptationsSorted)
    {
        // do real work
    }

我遇到的问题是foreach循环抛出异常

System.NotSupportedException was unhandled
  Message="Method 'System.String Replace(System.String, System.String,
    System.String)' has no supported translation to SQL."
  Source="System.Data.Linq"

我也想知道是否有更简洁的方法只使用一个LINQ查询。任何建议将不胜感激。

3 个答案:

答案 0 :(得分:2)

通过枚举查询(调用ToList)强制元素的水合作用。从那时起,您的操作将针对内存中的对象,并且这些操作将不会转换为SQL。

List<Adaptation> result =
  dbContext.Adaptation
  .Where(aun => aun.EventID = iep.EventID)
  .ToList();

result.ForEach(aun =>
  aun.Name = Regex.Replace(aun.Name,
    @"ADAPT([0-9])$", @"ADAPT0$1")
);
result = result.OrderBy(aun => aun.Name).ToList();

答案 1 :(得分:1)

使用您的逻辑实现IComparer<string>

var adaptationsUnsorted = from aun in dbContext.Adaptations
                          where aun.EventID == iep.EventID
                          select new Adaptation
                          {
                              StudentID = aun.StudentID,
                              EventID = aun.EventID,
                              Name = aun.Name,
                              Value = aun.Value
                          };

var adaptationsSorted = adaptationsUnsorted.ToList<Adaptation>().OrderBy(a => a.Name, new AdaptationComparer ());

foreach (Adaptation adaptation in adaptationsSorted)
{
    // do real work
}

public class AdaptationComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        string x1 = Regex.Replace(x, @"ADAPT([0-9])$", @"ADAPT0$1");
        string y1 = Regex.Replace(y, @"ADAPT([0-9])$", @"ADAPT0$1");
        return Comparer<string>.Default.Compare(x1, y1);
    }
}

我没有测试这段代码,但它应该可以完成这项工作。

答案 2 :(得分:0)

我想知道你是否可以将一个计算的+持久+索引字段添加到数据库中,这样做可以帮到你。编写一个将值作为整数获取的UDF(仅使用字符串值)会非常简单,但是您可以在数据库中对此列进行排序。这将允许您有效地使用SkipTake,而不是不断地将所有数据提取到.NET代码(这些数据根本无法扩展)。