在我的场景中,我想查询具有用户选择列名的表。因此,每当where
条件的列名称发生更改时,我都会尝试使用lambda
查询查询。
我完全不知道该怎么做,请帮我解决这个问题。或者建议是否有其他方法可以做到这一点?
string[] criteria = searchCriteria.Split('_');
var columnName = criteria[0];
var columnValue = criteria[1];
var subQry = (from e in ctx.tblEmployee
where (e.DateOfJoining <= startDate || (e.DateOfJoining.Value.Month == ApplyMonth && e.DateOfJoining.Value.Year == ApplyYear)) &&
monInputEmployee.Contains(e.Id) == flag
select new
{
e.Id,
e.Code,
e.FName,
e.DateOfJoining
}).ToList();
var eParam = Expression.Parameter(typeof(EmployeeDetail), "e");
var comparison = Expression.And(
Expression.Equal(Expression.Property(eParam, columnName), Expression.Constant(columnValue)),
Expression.Equal(Expression.Property(eParam, "CompId"), Expression.Constant(compId)));
var lambda = Expression.Lambda<Func<EmployeeDetail, bool>>(comparison, eParam);
var mainQry = subQry.Where(lambda);
答案 0 :(得分:2)
@Anup,我强烈建议你建立&amp;在调用 .ToList()函数之前执行动态查询。数据库上下文包含IQueryable&lt; TEntity&gt;如果你运行任何查询,它会将所有对象加载到内存中。
构建动态表达式的函数:
static Expression<Func<T, bool>> EqualComparer<T>(string propertyName, object propertyValue)
where T : class
{
var type = typeof (T);
ParameterExpression input = Expression.Parameter(type);
var prop = type.GetProperty(propertyName);
var value = Convert.ChangeType(propertyValue, prop.PropertyType);
var exProperty = Expression.Property(input, prop);
var eqExpre = Expression.Equal(exProperty, Expression.Constant(value));
return Expression.Lambda<Func<T, bool>>(eqExpre, input);
}
检查以下示例(使用内存中对象)
public class Person
{
public string Name { get; set; }
public uint Age { get; set; }
}
private void TestMethod()
{
//peoples collection
var persons = new[]
{
new Person {Age = 10, Name = "Ten"},
new Person {Age = 20, Name = "Twenty"},
new Person {Age = 30, Name = "Thirty"},
new Person {Age = 40, Name = "Forty"},
new Person {Age = 50, Name = "Fifty"}
};
//test query
const string column = "Age";
const int value = 20;
//build the expression & compile
var expression = EqualComparer<Person>(column, value).Compile();
//run the query
var selected =
from p in persons
where p.Name.Length > 0 && expression(p)
select p;
//iterate through results
foreach (var person in selected)
{
Debug.WriteLine(person.Name);
}
}
我希望它可以帮到你。
答案 1 :(得分:2)
以下是有用的文章Build Where Clause Dynamically in Linq,请查看Joe Albahari撰写的PredicateBuilder。
您可以使用Where clause
重写PredicateBuilder
,如下所示:
配偶你有SearchCriteria模型。
Public class SearchCritera
{
public DateTime? DateOfJoining { get; set; }
public int? CompanyId { get; set; }
public int? CategoryId { get; set; }
public EmployeeStatus? EmpStatus { get; set; }
}
var whereClause = PredicateBuilder.True<tblEmployee>();
if (searchCriteria.CompanyId.HasValue)
whereClause = whereClause.And(r => r.CompanyId == searchCriteria.CompanyId);
if (searchCriteria.CategoryId.HasValue)
whereClause = whereClause.And(r => r.Category == searchCriteria.CategoryId);
if (searchCriteria.CategoryId.HasValue)
whereClause = whereClause.And(r => r.EmpStatus == searchCriteria.EmpStatus);
if (searchCriteria.DateOfJoining.HasValue)
{
var dateClause1 = PredicateBuilder.True<tblEmployee>();
dateClause1.And(r => r.DateOfJoining <= searchCriteria.DateOfJoining);
var dateClause2 = PredicateBuilder.True<tblEmployee>();
dateClause2.And(r => re.DateOfJoining.Value.Month == searchCriteria.DateOfJoining.Month);
dateClause2.And(r => re.DateOfJoining.Value.Year == searchCriteria.DateOfJoining.Year);
dateClause1.Or(dateClause2);
whereClause.And(dateClause1)
}
var result = ctx.tblEmployee.AsExpandable().Where(whereClause);
答案 2 :(得分:2)
这就是我如何解决它,只需在Where
添加一个额外的lambda
: -
string[] criteria = searchCriteria.Split('_');
var columnName = criteria[0];
var columnValue = criteria[1];
var eParam = Expression.Parameter(typeof(EmployeeDetail), "e");
var comparison = Expression.Equal(Expression.Property(eParam, columnName), Expression.Convert(Expression.Constant(columnValue), Expression.Property(eParam, columnName).Type));
var lambda = Expression.Lambda<Func<EmployeeDetail, bool>>(comparison, eParam);
var subQry = (from e in ctx.tblEmployee
where (e.DateOfJoining <= startDate || (e.DateOfJoining.Value.Month == ApplyMonth && e.DateOfJoining.Value.Year == ApplyYear)) &&
monInputEmployee.Contains(e.Id) == flag
select new
{
e.Id,
e.Code,
e.FName,
e.DateOfJoining
}).Where(lambda)
.ToList();