在实体框架linq查询中将字符串转换为int并处理解析异常

时间:2012-10-01 16:27:25

标签: c# linq entity-framework

我遇到了这个问题,我有一张购物表

Purchases(Date DateTime, Number string)

我想创建一条新记录,所以我需要Max(Number),这里的问题是Number是字符串,我试过了

Purchases.Select(X=>int.Parse(X.Number)).Max()

但它可能会抛出异常,我创建了一个自定义ToInt()扩展程序,因此当我使用

Purchases.Select(X=>X.Number.ToInt()).Max()

它抛出一个异常,说我的ToInt()不能与linq查询一起使用,就像着名的ToString()

一样

所以我的问题是:有没有办法在linq查询&中将字符串强制转换为int。同时处理异常或将自定义函数集成到linq查询!!

这是我的扩展

    public static int ToInt(this string s)
    {
        try
        {
            return int.Parse(s);
        }
        catch
        {
        }
        return 0;
    }

2 个答案:

答案 0 :(得分:10)

第一种方式:

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代码,而不是尝试转换{{ 1}}进入SQL查询。我在我的一个Sandbox项目中创建了一个EF上下文并验证了它的工作原理。

答案 1 :(得分:2)

我不明白为什么你不想要这个例外,因为如果你的投射失败了,那就意味着你的应用程序发生了错误(或至少,所以我明白了)。我也不明白为什么要将数字作为字符串保存在数据库中。通常情况下,你会将它保存为一个数字,这样你就不必在以后处理这样的问题,如果有人试图插入错误的值,你就会在插入时失败。

但是 - 如果你想让这一行工作,你应该使用int.TryParse,如果值成功转换,它将返回true,并将值放在'out'成员中,该成员将不在查询中。像这样:

int tmp;
Purchases.Select(X=>int.TryParse(X.Number, out tmp) ? tmp : 0).Max()

而不是“0”放置一些不会弄乱你的逻辑的默认值。