I get this error when I'm doing the datatable serverside processing.
The error is thrown when I call this method with Ajax.
I think the problem is server-side coding and I didn't get the problem maybe it's a dynamic linq syntax error.
What is the right syntax for dynamic linq for this statement?
This is my C# code:
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);
}
And this is the script which I believe is fine:
@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>
}
You have a couple of problems here.
First, the list
is a really bad idea. It's reading the entire database table into memory, which, if it's large, could cause memory issues. But, more importantly, everything done after that will be done in C# on your web server, instead of by the database server. -- You are cutting the database server out of the very thing it was designed to do. You want to keep it as an
IQueryable<>until the very end, and that would be the only place you use.ToList().Next, we have the first
if(), which is mostly fine, but you knowsearchValueis a string, so why are you continually trying to convert it to a string? Why keep converting it to lower case? And again, noToList()Now, we get to the line you asked about. Basically, you are trying to get LINQ to use SQL syntax. Linq wants its own. But first, you have a logic error in your
if()statement. You have essentiallyif (!(A && B)). That's equal toif(!A || !B). What you really want isif(!A && !B).Getting the proper
OrderBystatement from a string is a tricky topic, requiring reflection, nicely documented in this question: Dynamic Order By in LinqFinally, we actually run the query of the dataserver, which is triggered by the
ToList().