public ActionResult Load()
{
string search = Request.Form.GetValues("search[value]")[0];
var draw = Request.Form.GetValues("draw").FirstOrDefault();
var start = Request.Form.GetValues("start").FirstOrDefault();
var length = Request.Form.GetValues("length").FirstOrDefault();
var sortColumn = Request.Form.GetValues("columns[" +
Request.Form.GetValues("order[0][column]").FirstOrDefault() + "][name]").FirstOrDefault();
var sortColumnDir = Request.Form.GetValues("order[0][dir]").FirstOrDefault();
int pageSize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int totalRecords = 0;
var v = (from a in DataContext.Company select a);
//Search
if (!string.IsNullOrEmpty(search) &&
!string.IsNullOrWhiteSpace(search))
{
v.Where(x => x.Name == search);
}
//Ordinamento
if (!(string.IsNullOrEmpty(sortColumn) && string.IsNullOrEmpty(sortColumnDir)))
v = v.OrderBy(sortColumn + " " + sortColumnDir);
totalRecords = v.Count();
var data = v.Skip(skip).Take(pageSize).ToList();
return Json(new
{
draw = draw,
recordsFiltered = totalRecords,
recordsTotal = totalRecords,
data = data
}, JsonRequestBehavior.AllowGet);
}
实际上,我正在使用Jquery Datatable和服务器端模式,这种方法运行得很好,但我想用它来做法。 通过这种方式,我可以重用我的方法。 第一个问题是在“搜索”部分,因为我不知道如何动态传递数据库表(datacontext)。现在通过“var v”,但我通过表“公司”所以它是静态的(我需要将表作为参数传递。
无论如何,如果我解决它,我需要将lamba表达式作为参数传递,因为我想搜索特定的表列。
然而,我的问题的真正问题是:如何使这个函数动态化,以便我可以使用它而不重复代码?
谢谢
答案 0 :(得分:0)
你传递给你的功能两个功能。 第一个Func>获取DbContext并返回选定的集合。
第二个是过滤函数,它接受一个元素并对其进行过滤。
这会改变这一行:
v.Where(x => x.Name == search);
修改强>
您的功能签名将如下所示:
public IEnumerable<T> Search(IQueryable<T> entites, Func<T,bool> filter)
{
// your code here
}
答案 1 :(得分:0)
我尝试为Jquery DataTable创建一个小的查询构建器。可能会有错误,但这将是一个良好的开端。这可能会对你有所帮助。
我将此useful answer用作模型绑定的参考。我不在这里编写代码,不重复它。
使阅读请求参数的过程标准化
public ActionResult Load(DTParameterModel dtParameters)
{
// do some thing
}
Jquery DataTable的查询构建器。
搜索多列
按多列排序
JqueryDataTableQueryBuilder.cs
public class JqueryDataTableQueryBuilder
{
private static readonly MethodInfo OrderByMethod = typeof(Queryable)
.GetMethods().
Single(method => method.Name == "OrderBy"
&& method.GetParameters().Length == 2);
private static readonly MethodInfo OrderByDescendingMethod = typeof(Queryable)
.GetMethods().Single(method => method.Name == "OrderByDescending"
&& method.GetParameters().Length == 2);
public static IQueryable<T> BuildQuery<T>(IQueryable<T> query, DTParameterModel dtParameters)
{
IQueryable<T> q = query;
//I skiped regex search
var searchColumns = dtParameters.Columns.Where(c => c.Searchable).Select(c => c.Name).ToArray();
if (searchColumns.Length > 0)
if (!string.IsNullOrEmpty(dtParameters.Search.Value) && !string.IsNullOrWhiteSpace(dtParameters.Search.Value))
{
int i = 0;
var par = Expression.Parameter(typeof(T), "x");
Expression exp = Expression.Constant(false);
//we need to bind search expressions with 'OR'
while (i < searchColumns.Length)
{
var expNext = GetSearchExpression<T>(searchColumns[i], dtParameters.Search.Value,par);
var expInvoke = Expression.Invoke(expNext, par);
exp = Expression.OrElse(exp, expNext.Body);
i++;
}
var ex = Expression.Lambda<Func<T, bool>>(exp,par);
q = q.Where(ex);
}
// order by
DTColumn[] columns = dtParameters.Columns.ToArray();
foreach (var order in dtParameters.Order)
{
var orderColumn = columns[order.Column].Name;
var dir = order.Dir;
q = OrderByQuery(q, orderColumn, dir);
}
return q;
}
public static object GetDTResult<T>(DTParameterModel dtParameters, IQueryable<T> query,Expression<Func<T,object>> func = null)
{
var totalRecords = query.Count();
query = query.Skip(dtParameters.Start).Take(dtParameters.Length);
object data = func == null ? (object) query.ToArray() : query.Select(func).ToArray();
var result = new
{
draw = dtParameters.Draw,
recordsFiltered = totalRecords,
recordsTotal = totalRecords,
data = data
};
return result;
}
static Expression<Func<T, bool>> GetSearchExpression<T>(string propertyName, string propertyValue,ParameterExpression p)
{
var propertyExp = Expression.Property(p, propertyName);
// we need to call string.Contains method
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var valueExp = Expression.Constant(propertyValue, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, valueExp);
return Expression.Lambda<Func<T, bool>>(containsMethodExp, p);
}
static IQueryable<T> OrderByQuery<T>(IQueryable<T> source, string propertyName, string dir)
{
IQueryable<T> query = source;
Type entityType = typeof(T);
if (entityType.GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance) == null)
throw new NullReferenceException("order by " + propertyName);
ParameterExpression paramterExpression = Expression.Parameter(entityType);
Expression orderByProperty = Expression.Property(paramterExpression, propertyName);
LambdaExpression lambda = Expression.Lambda(orderByProperty, paramterExpression);
MethodInfo genericMethod = !string.IsNullOrEmpty(dir) && !string.IsNullOrWhiteSpace(dir) && dir.ToUpper().Equals("DESC")
? OrderByDescendingMethod.MakeGenericMethod(entityType, orderByProperty.Type)
: OrderByMethod.MakeGenericMethod(entityType, orderByProperty.Type);
object ret = genericMethod.Invoke(null, new object[] { query, lambda });
return (IQueryable<T>)ret;
}
}
是:强>
实体模型:
public partial class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
public DateTime CreatedDate { get; set; }
}
<强>标记:强>
<script type="text/javascript">
$(function () {
$('#example').DataTable({
"processing": true,
"serverSide": true,
"ajax": "/JqTableTest/Load"
});
});
</script>
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th data-orderable="true" data-searchable="false" data-name="Id" data-data="Id">Id</th>
<th data-orderable="true" data-searchable="true" data-name="Name" data-data="Name">First name</th>
<th data-orderable="true" data-searchable="true" data-name="LastName" data-data="LastName"> Last name</th>
</tr>
</thead>
</table>
<强> CONTROLER:强>
public ActionResult Load(DTParameterModel dtParameters)
{
using (Data.Entities context = new Data.Entities())
{
var query = context.Customer.AsQueryable();
query = JqueryDataTableQueryBuilder.BuildQuery(query, dtParameters);
var result = JqueryDataTableQueryBuilder.GetDTResult(dtParameters, query);
return Json(result, JsonRequestBehavior.AllowGet);
}
}
查询:
-- count
SELECT [GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM [dbo].[Customer] AS [Extent1]
) AS [GroupBy1]
-- result
SELECT TOP (10)
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent1].[LastName] AS [LastName],
[Extent1].[CreatedDate] AS [CreatedDate]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[LastName] AS [LastName], [Extent1].[CreatedDate] AS [CreatedDate], row_number() OVER (ORDER BY [Extent1].[Id] ASC) AS [row_number]
FROM [dbo].[Customer] AS [Extent1]
) AS [Extent1]
WHERE [Extent1].[row_number] > 0
ORDER BY [Extent1].[Id] ASC
您可以指定结果列
public ActionResult Load(DTParameterModel dtParameters)
{
using (Data.Entities context = new Data.Entities())
{
var query = context.Customer.AsQueryable();
query = JqueryDataTableQueryBuilder.BuildQuery(query, dtParameters);
var result = JqueryDataTableQueryBuilder.GetDTResult(dtParameters, query, a => new
{
a.Id,
a.Name,
a.LastName
});
return Json(result, JsonRequestBehavior.AllowGet);
}
}
查询:
SELECT TOP (10)
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent1].[LastName] AS [LastName]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[LastName] AS [LastName], row_number() OVER (ORDER BY [Extent1].[Id] ASC) AS [row_number]
FROM [dbo].[Customer] AS [Extent1]
) AS [Extent1]
WHERE [Extent1].[row_number] > 0
ORDER BY [Extent1].[Id] ASC
请求搜索参数:
draw:6
columns[0][data]:Id
columns[0][name]:Id
columns[0][searchable]:false
columns[0][orderable]:true
columns[0][search][value]:
columns[0][search][regex]:false
columns[1][data]:Name
columns[1][name]:Name
columns[1][searchable]:true
columns[1][orderable]:true
columns[1][search][value]:
columns[1][search][regex]:false
columns[2][data]:LastName
columns[2][name]:LastName
columns[2][searchable]:true
columns[2][orderable]:true
columns[2][search][value]:
columns[2][search][regex]:false
order[0][column]:0
order[0][dir]:asc
start:0
length:10
search[value]:abc
search[regex]:false
查询:
SELECT TOP (10)
[Filter1].[Id] AS [Id],
[Filter1].[Name] AS [Name],
[Filter1].[LastName] AS [LastName]
FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[LastName] AS [LastName], row_number() OVER (ORDER BY [Extent1].[Id] ASC) AS [row_number]
FROM [dbo].[Customer] AS [Extent1]
WHERE ([Extent1].[Name] LIKE N'%abc%') OR ([Extent1].[LastName] LIKE N'%abc%')
) AS [Filter1]
WHERE [Filter1].[row_number] > 0
ORDER BY [Filter1].[Id] ASC