我有一个要动态查询的数据集。如果我明确定义字段名称,则此代码可以正常工作,但是我不想这样做。我想使用变量作为字段名称来动态查询数据。我应该如何处理?
这有效:
var dataField = "DemandStatusName";
var searchParam = form.GetValues("columns[" + j + "][search][value]").FirstOrDefault();
if(searchParam != "")
{
dataSet = (from a in dataSet
where a.DemandStatusName.Contains(searchParam)
select a);
}
但这不是:
var dataField = "DemandStatusName";
var searchParam = form.GetValues("columns[" + j + "][search][value]").FirstOrDefault();
if(searchParam != "")
{
dataSet = (from a in dataSet
where dataField.Contains(searchParam)
select a);
}
答案 0 :(得分:1)
我应该如何处理?
LINQ的主要优点之一是您可以安全地输入类型。通过动态查询它,您固有地失去了这一好处。尽管并不是真正的“动态”,但您可以通过编写扩展方法来保留此优势,该方法包括要查询的特定字段:
public static IQueryable<MyTable> WhereContains(this IQueryable<MyTable> source, string field, string value)
{
switch (field)
{
case nameof(MyTable.SomeField):
return source.Where(a => a.SomeField.Contains(value));
case nameof(MyTable.SomeOtherField):
return source.Where(a => a.SomeOtherField.Contains(value));
// ... etc
default:
throw new ArgumentOutOfRangeException($"Unexpected field {field}");
}
}
这样,您的代码可以调用以下内容:
var dataField = "DemandStatusName";
var searchParam = form.GetValues("columns[" + j + "][search][value]").FirstOrDefault();
dataset.WhereContains(dataField, searchParam).OrderBy(a => a.Whatever)
也就是说,要从字面上回答您的问题,从技术上讲,您可以动态地构建LINQ表达式。可能看起来像这样,但是请注意性能会很差,意外的值可能会破坏它和/或打开一些安全漏洞,尤其是如果这些漏洞来自用户输入:
var table = Expression.Parameter(typeof(MyTable));
var property = Expression.PropertyOrField(table, dataField);
var param = Expression.Constant(searchParam);
var contains = Expression.Call(property, "Contains", Type.EmptyTypes, searchParam);
var expression = Expression.Lambda<Func<MyTable,bool>>(contains, table);
var result = dataset.Where(expression);
答案 1 :(得分:0)
是否需要使用LINQ?动态SQL(带有参数)会容易得多。
var dataField = "DemandStatusName";
var searchParam = form.GetValues("columns[" + j + "][search][value]").FirstOrDefault();
var sql = string.Format("select * from tableName where {0} = @param", dataField);
if(searchParam != "")
{
dataSet = context.Database.SqlQuery<YourEntity>(sql,
new SqlParameter("param", searchParam));
}