繁体   English   中英

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

[英]Select Max, but only on numeric values with LINQ to Entities

我试图从sys_id列是varchar类型的表中选择max sys_id 有些行包含文本,但我只关心数值。

我尝试了以下一些代码,但它们不起作用 - 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做到这一点?

使用SqlFunctions.IsNumeric和Cast

iQueryableSource
.Where(x => SqlFunctions.IsNumeric(x.Number + ".0e0") == 1) // see explanation about .0e0 below
.Select(x => x.Number)
.Cast<int>()
.Max()

UPDATE

您可以发现与字符串中的点或货币符号相关的问题,但仍然会获得IsNumeric == 1 因为你只想要整数,你应该在字符串中添加一个.0e0 ,就像这样SqlFunctions.IsNumeric(x.Number + ".0e0") == 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));

Max(p => p.sys_id)); 这不会像你期望的那样......

您期望获得以下结果:

public static int Max(
    this IEnumerable<int> source
)

但实际上你正在调用IEnumerable<string>的重载。 你可能知道"2" > "10"评估为真。 这可能解释了你的结果。

基本上就是做Where(p => IsNumber(p)).Cast<int>().Max(); 你会得到你想要的东西。

不是我知道的。 如果它不是一个大表,那么您可以通过执行以下操作返回所有结果:

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特定的功能,而且速度会快得多。

您将获得异常,因为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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM