我正在尝试从sys_id
列为sys_id
类型的表中选择最大varchar
。有些行包含文本,但我只关心数值。
我尝试了以下一些代码,但它们不起作用 - LINQ to Entities似乎不支持此操作。
public string GetSysID()
{
using (var context = new DbEntities())
{
int i;
// var intQuery = context.myTable.Where(t => int.TryParse(t.sys_id, out i)).Max();
int intQuery = Convert.ToInt32(context.myTable.Where(p => IsNumber(p.sys_id)).Max(p => p.sys_id));
//return context.drawings.Max(p => p.sys_id);
return intQuery.ToString();
}
}
public static bool IsNumber(string value)
{
int n;
return int.TryParse(value, out n);
}
有没有办法使用LINQ to Entities做到这一点?
答案 0 :(得分:6)
使用SqlFunctions.IsNumeric和Cast
iQueryableSource
.Where(x => SqlFunctions.IsNumeric(x.Number + ".0e0") == 1) // see explanation about .0e0 below
.Select(x => x.Number)
.Cast<int>()
.Max()
<强>更新强>
您可以发现与字符串中的点或货币符号相关但仍然获得IsNumeric == 1
的问题。因为您只想要整数,您应该在字符串中添加.0e0
,例如SqlFunctions.IsNumeric(x.Number + ".0e0") == 1
有关详细信息,请参阅this question和this blog post
答案 1 :(得分:1)
试试这个:
context.myTable
.Where(c => c.sys_id.All(char.IsDigit))
.Max(c => int.Parse(c.sys_id));
如果不起作用请尝试Contains
,如下所示:
var numbers = new [] { '0','1','2','3','4','5','6','7','8','9' };
var value = context.myTable
.Where(c => c.sys_id.All(numbers.Contains))
.Max(c => int.Parse(c.sys_id));
答案 2 :(得分:0)
Max(p => p.sys_id));
这不会像你期望的那样......
您希望得到以下结果;
public static int Max(
this IEnumerable<int> source
)
但实际上你正在调用IEnumerable<string>
的重载。你可能知道"2" > "10"
评估为真。这可能解释了你的结果。
基本上只做Where(p => IsNumber(p)).Cast<int>().Max();
,你就会得到你想要的东西。
答案 3 :(得分:0)
不是我知道的。如果它不是一个大表,那么你可以通过执行以下操作返回所有结果:
int intQuery = Convert.ToInt32(context.myTable.ToList().Where(p => IsNumber(p.sys_id)).Max(p => int.Parse(p.sys_id)));
请注意,我在Max方法中添加了int.Parse - 否则,正如@evanmcdonnal所指出的,值2将高于10,因为它将是字符串比较。
然而,使用我的示例对于更大的表来说效率不高。我发现LinqToEntities并不适合这个目的。也许尝试创建一个可以在db上下文中调用的存储过程,或者使用视图或其他东西。这样你就可以利用SQL特定的功能,而且速度会快得多。
答案 4 :(得分:0)
您遇到异常,因为Linq-Entities无法将IsNumber()方法转换为sql命令
你可以试试这个
using (var context = new DbEntities())
{
//First get all the sysIds
var sysIds = (from tab in context.myTable
select tab.sys_id).ToList();
//Then use the custom method
int intQuery = Convert.ToInt32(sysIds.Where(p => IsNumber(p.sys_id)).Max(p => p.sys_id));
return intQuery.ToString();
}