EntityFramework:OrderBy() 数字 属性 当映射列类型为文本时
EntityFramework: OrderBy() numeric property when mapped column type is textual
return JsonConvert.SerializeObject(new Entities()
.Student_Master
.Where(k => k.Student_Location == Location && k.Student_Course == Program)
.OrderBy(i => i.Student_Batch)
.Select(i => i.Student_Batch)
.Distinct()
.ToList());
输出:
[23,24,28,25,30,26,27,29]
需要输出
[23,24,25,26,27,28,29,30]
我尝试使用 OrderBy(i => i.Student_Batch)
但在数据库 Student_Batch
中数据类型是 string
所以排序不正确
我试着关注
var data=new Entities().Student_Master.Where(k => k.Student_Location == Location && k.Student_Course == Program).OrderBy(i => i.Student_Batch).Select(i => i.Student_Batch).Distinct().ToList();
foreach(var obj in data)
{
//converted string to int then store in array
}
有什么简单的方法吗?
.Distinct()
删除任何 .OrderBy()
子句,因为根据定义,Distinct()
(或 SQL 中的 DISTINCT
)returns 一个非不同值的有序集合。您需要在 .Distinct()
调用之后链接 .OrderBy()
调用。
当您想按数值对它们进行排序时,将值作为字符串确实会产生问题。如果不能更改数据库模式,可以使用 this method 将值投影为整数,然后执行 .Distinct()
和 .OrderBy()
.
最后,您应该在使用 Entities 对象后正确处理它,以关闭数据库连接,最好将其包含在 using
指令中。
好的,因为问题出在排序上。您的选择很少,我将展示其中的 2 个。首先是您可以使用 Array.Sort()
这很常见:
string[] values = new Entities()
.Student_Master
.Where(k => k.Student_Location == Location && k.Student_Course == Program).Select(i => i.Student_Batch)
.Distinct().ToArray();
Array.Sort(values); // all you need.
第二种常见方法是创建自定义比较器并在内部使用它 OrderBy
:
public class MeComparer : IComparer<string> {
public int Compare(string stringA, string stringB) {
// your compare logic goes here...
// eg. return int.Parse(stringA) - int.Parse(stringB)
}
}
// and use it like
return JsonConvert.SerializeObject(new Entities()
.Student_Master
.Where(k => k.Student_Location == Location && k.Student_Course == Program)
.Select(i => i.Student_Batch)
.Distinct()
.ToList()
.OrderBy(i => i.Student_Batch, new MeComparer()) // <-- HERE
);
由于 Linq2Entities 不支持从字符串到 int 的转换(既不使用 int.Parse
也不使用 Convert.ToInt32
),您必须使用 [=14] 将 IQueryAble
转换为 IEnumerable
=].当然,这是性能方面的噩梦,但是由于 SQL 无法通过即时转换对字符串进行整数运算,这就是您所需要的。
顺便说一句:使用ToArray
或ToList
也会枚举集合并放入内存。
return JsonConvert.SerializeObject(new Entities()
.Student_Master
.Where(k => k.Student_Location == Location && k.Student_Course == Program)
.OrderBy(i => i.Student_Batch)
.Select(i => i.Student_Batch)
.Distinct()
.ToList());
输出:
[23,24,28,25,30,26,27,29]
需要输出
[23,24,25,26,27,28,29,30]
我尝试使用 OrderBy(i => i.Student_Batch)
但在数据库 Student_Batch
中数据类型是 string
所以排序不正确
我试着关注
var data=new Entities().Student_Master.Where(k => k.Student_Location == Location && k.Student_Course == Program).OrderBy(i => i.Student_Batch).Select(i => i.Student_Batch).Distinct().ToList();
foreach(var obj in data)
{
//converted string to int then store in array
}
有什么简单的方法吗?
.Distinct()
删除任何 .OrderBy()
子句,因为根据定义,Distinct()
(或 SQL 中的 DISTINCT
)returns 一个非不同值的有序集合。您需要在 .Distinct()
调用之后链接 .OrderBy()
调用。
当您想按数值对它们进行排序时,将值作为字符串确实会产生问题。如果不能更改数据库模式,可以使用 this method 将值投影为整数,然后执行 .Distinct()
和 .OrderBy()
.
最后,您应该在使用 Entities 对象后正确处理它,以关闭数据库连接,最好将其包含在 using
指令中。
好的,因为问题出在排序上。您的选择很少,我将展示其中的 2 个。首先是您可以使用 Array.Sort()
这很常见:
string[] values = new Entities()
.Student_Master
.Where(k => k.Student_Location == Location && k.Student_Course == Program).Select(i => i.Student_Batch)
.Distinct().ToArray();
Array.Sort(values); // all you need.
第二种常见方法是创建自定义比较器并在内部使用它 OrderBy
:
public class MeComparer : IComparer<string> {
public int Compare(string stringA, string stringB) {
// your compare logic goes here...
// eg. return int.Parse(stringA) - int.Parse(stringB)
}
}
// and use it like
return JsonConvert.SerializeObject(new Entities()
.Student_Master
.Where(k => k.Student_Location == Location && k.Student_Course == Program)
.Select(i => i.Student_Batch)
.Distinct()
.ToList()
.OrderBy(i => i.Student_Batch, new MeComparer()) // <-- HERE
);
由于 Linq2Entities 不支持从字符串到 int 的转换(既不使用 int.Parse
也不使用 Convert.ToInt32
),您必须使用 [=14] 将 IQueryAble
转换为 IEnumerable
=].当然,这是性能方面的噩梦,但是由于 SQL 无法通过即时转换对字符串进行整数运算,这就是您所需要的。
顺便说一句:使用ToArray
或ToList
也会枚举集合并放入内存。