我正在使用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查询。任何建议将不胜感激。
答案 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(仅使用字符串值)会非常简单,但是您可以在数据库中对此列进行排序。这将允许您有效地使用Skip
和Take
,而不是不断地将所有数据提取到.NET代码(这些数据根本无法扩展)。