选择Max,但仅限于具有LINQ to Entities的数值

时间:2014-02-17 23:41:38

标签: c# sql linq entity-framework linq-to-entities

我正在尝试从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做到这一点?

5 个答案:

答案 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 questionthis 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();
}