当我在做数据表服务器端处理时,我得到这个错误。
当我用Ajax调用这个方法时抛出错误。
我认为问题是服务器端编码,我没有得到这个问题,可能是动态linq语法错误。
这个语句的动态linq的正确语法是什么?
这是我的c#代码:public ActionResult Indexer()
{
int start = Convert.ToInt32(Request["start"]);
int length = Convert.ToInt32(Request["length"]);
string searchValue = Request["search[value]"];
string sortColumnName = Request["columns["+Request["order[0][column]"] + "][name]"];
string sortDirection = Request["order[0][dir]"];
int recordsTotal = 0;
List<Employee> Employee = _context.Employees.ToList();
if (!string.IsNullOrEmpty(searchValue)) //filter
{
Employee = Employee.Where(x => x.Emp_ID.ToString().Contains(searchValue.ToString()) ||
x.First_Name.ToLower().Contains(searchValue.ToLower()) ||
x.Last_Name.ToLower().Contains(searchValue.ToLower()) ||
x.Gender.ToLower().Contains(searchValue.ToLower()) ||
x.Salary.ToString().Contains(searchValue.ToString())).ToList();
}
//sorting
if (!(string.IsNullOrEmpty(sortColumnName) && string.IsNullOrEmpty(sortDirection)))
{
// This line throws the error
Employee = Employee.OrderBy(sortColumnName + " " + sortDirection).ToList();
}
// Paging
Employee = Employee
.Skip(start).Take(length)
.ToList<Employee>();
recordsTotal = Employee.Count();
return Json(new { data = Employee }, JsonRequestBehavior.AllowGet);
}
这是我认为很好的脚本:
@section scripts {
<script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function () {
$('#mytable').DataTable({
"ajax": {
"url": "/Home/Indexer",
"type": "POST",
"datatype": "josn",
},
"columns": [
{ "data": "Emp_ID", "name": "Emp_Id" },
{ "data": "First_Name", "name": "First_Name" },
{ "data": "Last_Name", "name": "Last_Name" },
{ "data": "Gender", "name": "Gender" },
{ "data": "Salary", "name": "Salary" },
],
"serverSide": "true",
"order": [0, "acs"],
"processing": "true",
});
})
</script>
}
你这里有几个问题。
首先,列表
List<Employee> Employee = _context.Employees.ToList();
是一个非常糟糕的主意。它将整个数据库表读入内存,如果它很大,可能会导致内存问题。但是,更重要的是,之后的所有工作都将在web服务器上用c#完成,而不是在数据库服务器上。——你正在把数据库服务器从它设计的工作中剥离出来。您希望将其保留为IQueryable<>
,直到最后,这将是您使用.ToList()
的唯一地方。
IQueryable<Employee> Employee = _context.Employees;
接下来,我们有第一个if()
,这很好,但是您知道searchValue
是一个字符串,那么为什么您要不断地尝试将其转换为字符串?为什么要把它转换成小写?同样,没有ToList()
if (!string.IsNullOrEmpty(searchValue)) //filter
{
searchValue = searchValue.ToLower();
Employee = Employee.Where(x => x.Emp_ID.ToString().Contains(searchValue) ||
x.First_Name.ToLower().Contains(searchValue) ||
x.Last_Name.ToLower().Contains(searchValue) ||
x.Gender.ToLower().Contains(searchValue) ||
x.Salary.ToString().Contains(searchValue));
}
现在,我们到了你问的那条线。基本上,您正在尝试让LINQ使用SQL语法。Linq想要自己的。但首先,你有一个逻辑错误在你的if()
语句。实际上是if (!(A && B))
。它等于if(!A || !B)
。你真正想要的是if(!A && !B)
。
if (!string.IsNullOrEmpty(sortColumnName) && !string.IsNullOrEmpty(sortDirection))
{
从字符串中获得正确的OrderBy
语句是一个棘手的主题,需要反射,在这个问题中很好地记录:Linq
中的动态排序最后,我们实际运行了由ToList()
触发的数据服务器的查询。
// Paging
var lstEmployee = Employee
.Skip(start).Take(length)
.ToList();
recordsTotal = lstEmployee.Count();
return Json(new { data = lstEmployee }, JsonRequestBehavior.AllowGet);