在Linq查询中搜索十进制值

时间:2015-04-14 08:06:25

标签: c# linq entity-framework

我有这个搜索字词

[HttpPost]
public ActionResult Index(string searchString)
{
    if (!String.IsNullOrEmpty(searchString))
    {
        students = students.Where(s => s.FIRST_NAME.Contains(searchString) 
            || s.LAST_NAME.Contains(searchString)
            || s.PERSONAL_NUMBER.Contains(searchString)
            || s.ACD_UNI_DEGREES.DEGREE.Contains(searchString)
            || s.ACD_UNI_FACULTIES.FACULTY.Contains(searchString)
            || s.ACD_UNI_SPECIALIZATIONS.SPECIALIZATION.Contains(searchString)
            || SqlFunctions.StringConvert(s.SEMESTER).Contains(searchString) 
            || s.COR_PAYER_STATUS.NAME.Contains(searchString)
            || SqlFunctions.StringConvert(s.CREDIT_COUNT).Contains(searchString));
    }

    return View(students.ToList());
}

但是在调试时会引发异常:

  

System.NotSupportedException:指定的方法'System.String   字符串上的StringConvert(System.Nullable`1 [System.Decimal])'   'System.Data.Objects.SqlClient.SqlFunctions'无法翻译成   LINQ to Entities存储表达式。

问题在于:

SqlFunctions.StringConvert(s.SEMESTER).Contains(searchString)

SEMESTER 是十进制的, searchString 是字符串。 我怎样才能改善这一点?

3 个答案:

答案 0 :(得分:1)

您应该确保使用System.Data.Entity.SqlServer.SqlFunctions。我重写了你的查询,一切正常。

答案 1 :(得分:0)

虽然这是一个老问题发布答案,以便其他人会正确地做到这一点 首先要纠正的是我们需要将第一个整数转换为十进制然后进行搜索,假设可搜索列的数据类型也是十进制数

首先将搜索字符串转换为十进制字

               decimal dec;
               bool IsDecimal = decimal.TryParse(searchString, out dec);

               // Truncating search to 2 digits this should be equal to your db            
               // column precision so that rounding case are handled properly 
               decimal TruncateDigits = -1;
               if (IsDecimal)
                   TruncateDigits = Convert.ToDecimal(Math.Truncate(dec * 100) / 100); 

现在您的搜索字段与您的 db coloumn precison 相同并准备好搜索

    students = students.Where(s => s.FIRST_NAME.Contains(searchString) 
            || s.LAST_NAME.Contains(searchString)
            || s.PERSONAL_NUMBER.Contains(searchString)
            || s.ACD_UNI_DEGREES.DEGREE.Contains(searchString)
            || s.ACD_UNI_FACULTIES.FACULTY.Contains(searchString)
            || s.ACD_UNI_SPECIALIZATIONS.SPECIALIZATION.Contains(searchString)
            || (IsDecimal && (decimal.Round(s.SEMESTER, 2) == TruncateDigits)) 

需要注意的重要事项

      (IsDecimal && (decimal.Round(s.SEMESTER, 2) == TruncateDigits)) 

这里我们将再次舍入到db列精度来处理舍入。

同样 SqlFunctions.StringConvert会在内部进行舍入所以如果你的数字是db是68.88并且你正在搜索68它就不会搜索,因为StringConvert会给你69(舍入)所以如果你想搜索对于68,那么你需要使用 Floor 功能
    像

这样的东西
     SqlFunctions.StringConvert(decimal.Floor(s.SEMESTER)).Contains(searchString) 

希望这会有所帮助!!!

答案 2 :(得分:0)

我现在正以完全相同的原则面对同样的问题。经过长时间的搜索,我终于找到了:

[HttpPost]
public ActionResult Index(string searchString){
    searchString = searchString.Replace(",", ".");

    if (!String.IsNullOrEmpty(searchString)){
        students = students.Where(s => s.FIRST_NAME.Contains(searchString) 
        || s.LAST_NAME.Contains(searchString)
        || s.PERSONAL_NUMBER.Contains(searchString)
        || s.ACD_UNI_DEGREES.DEGREE.Contains(searchString)
        || s.ACD_UNI_FACULTIES.FACULTY.Contains(searchString)
        || s.ACD_UNI_SPECIALIZATIONS.SPECIALIZATION.Contains(searchString)
        || (s.SEMESTER.ToString()).Contains(searchString) 
        || s.COR_PAYER_STATUS.NAME.Contains(searchString)
        || SqlFunctions.StringConvert(s.CREDIT_COUNT).Contains(searchString));
    }
    return View(students.ToList());
}

您通常使用decimalstring投射到ToString()。然而,布雷瑟特是这里的法宝: (s.SEMESTER.ToString()) 这有所作为。

此语法将使您可以使用符号.进行搜索(例如:1203.4而不是1203,4)。并不是很友好。

要解决此问题,请在您的searchString上使用.Replace(',', '.')。这将把技巧应用到后台,没有人会注意到。

我希望它能帮助遇到同样问题的任何人。