在entity frameworklinq查询中将字符串转换为int并处理解析exception
我有这个问题,我有一张桌子可供购买
Purchases(Date DateTime, Number string)
我想创建一个新的记录,所以我需要Max(Number),这里的问题是Number是一个字符串 ,我试过了
Purchases.Select(X=>int.Parse(X.Number)).Max()
但它可能会抛出exception,我创建了一个自定义的ToInt()
扩展,所以当我使用时
Purchases.Select(X=>X.Number.ToInt()).Max()
它抛出一个exception,说我的ToInt()不能与着名的ToString()相同的linq查询一起使用
所以我的问题是:有没有办法在linq查询中同时将字符串转换为int并同时处理exception或将自定义函数集成到linq查询中!!
这是我的扩展
public static int ToInt(this string s) { try { return int.Parse(s); } catch { } return 0; }
第一种方式:
var numbers = Purchases.Select(x => x.Number).ToList(); int temp; int max = numbers.Select(n => int.TryParse(n, out temp) ? temp : 0).Max(); Console.WriteLine("Max: {0}", max);
第二种方式:
int temp2; int max2 = Purchases.Select(x => x.Number).ToList().Select(n => int.TryParse(n, out temp2) ? temp2 : 0).Max(); Console.WriteLine("Max 2: {0}", max2);
关键是这两种方式的.ToList()
。 它从数据库中获取所有string
数据,因此当您在结果上调用int.TryParse
时,数据库查询已经运行,因此它使用纯CLR代码,而不是尝试将int.TryParse
转换为SQL查询。 我在我的一个Sandbox项目中创建了一个EF上下文并validation了它的工作原理。
我不明白为什么你不想要这个例外,因为如果你没有投射,那么这意味着你的应用程序发生了错误(至少,所以我明白了)。 我也不明白为什么要把数字作为字符串保存在数据库中。 通常,你会将它保存为一个数字,这样你就不必再处理这样的问题,如果有人试图插入错误的值,你就会在插入时失败。
但是 – 如果你想让这一行工作,你应该使用int.TryParse
,如果值成功int.TryParse
,它将返回true,并将值放在’out’成员中,该成员将不在查询中。 像这样:
int tmp; Purchases.Select(X=>int.TryParse(X.Number, out tmp) ? tmp : 0).Max()
而不是“0”放一些不会弄乱你的逻辑的默认值。