12

我有这个问题,我有一个购买表

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() 不能与著名的 ToString() 相同的 linq 查询一起使用

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

这是我的扩展

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

2 回答 2

17

第一种方式:

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 查询。我在我的一个沙盒项目中创建了一个 EF 上下文并验证了它的工作原理。

于 2012-10-01T16:52:36.367 回答
2

我不明白你为什么不想要这个例外,因为如果你的强制转换失败,那么这意味着你的应用程序出了点问题(或者至少,我明白了)。我也不明白为什么要将应该是数字的内容保存为数据库中的字符串。通常,您会将其保留为数字,这样您以后就不必处理此类问题,如果有人尝试插入错误的值,您将在插入时失败。

但是 - 如果你确实想让这条线正常工作,你应该使用int.TryParse如果成功转换的值将返回 true 并将值放入 'out' 成员中,该成员将不在查询中。像这样:

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

而不是“0”,而是放置一些不会与您的逻辑混淆的默认值。

于 2012-10-01T16:35:16.280 回答