我想用不同的键搜索我的数据库。根据输入的情况,可能有1个键到10个键。有没有办法动态地将 OR/AND 子句添加到我的 Linq 查询中?
keys[k] // I have my keys in this array
var feedList = (from feed in ctx.Feed
where feed.content.contains(keys[0])
&& feed.content.contains(keys[1])
&& ... // continues with the keys.length
select new {
FeedId = feed.DuyuruId,
FeedTitle = feed.FeedTitle,
FeedContent = feed.FeedContents,
FeedAuthor = user.UserName + " " +User.UserSurname
}
对于 AND 子句来说很简单:
var feedList = from feed in ctx.Feed;
foreach(var key in keys){
feedList = feedList.Where(x=> content.contains(key));
}
var resultQuery = feedList.Select(x=> new {....});
对于 OR,您需要使用
Expressions
或尝试 LinqKit 及其谓词:
var predicate = PredicateBuilder.False<TypeOfYourEntity>();
foreach(var key in keys){
predicate = predicate.Or(x=> content.contains(key));
}
var resultQuery = ctx.Feed.Where(predicate).Select(x=> new {....});
可以使用LINQ的扩展方法
ctx.Feed.Where(f => {
//Your logic here
if(something != null){
return f.Property == something
}
}).Select( new { FeedId = feed.DuyuruId,
FeedTitle = feed.FeedTitle,
FeedContent = feed.FeedContents,
FeedAuthor = user.UserName + " " +User.UserSurname })
你可以做这样的事情。请记住,这可能会带来一些开销
var students = ctx.Students;
if (!String.IsNullOrWhiteSpace(SearchParams.Name))
students = from s in students where s.Name.StartsWith(SearchParams.Name)
if (!String.IsNullOrWhiteSpace(SearchParams.Surname))
students = from s in students where s.Surname.StartsWith(SearchParams.Surname)
我想提供一个示例,说明 @mellamokb 的答案如何适用于我的场景,以可能帮助任何需要相当动态的
linq
查询的人。
在我的示例中,我只是对
datatable
类进行了扩展,这样我就可以检查数据库中是否存在一行数据,这样就不会抛出 SQL
主键异常。
/// <summary>
///
/// </summary>
/// <param name="DT"></param>
/// <param name="ColumnNames">Columns to check in affected table.</param>
/// <param name="ItemtoChecks">Values to check in affected column.</param>
/// <returns></returns>
public static bool TableContains(this DataTable DT, string[] ColumnNames, object[] ItemtoChecks)
{
var result = from row in DT.AsEnumerable()
where ColumnNames.All(
r => row.Field<object>(r).ToString() == Convert.ToString(
ItemtoChecks[ColumnNames.ToList()
.FindIndex(p => p.Equals(r, StringComparison.OrdinalIgnoreCase))]))
select row;
return (result.Count() > 0);
}
此方法允许您向
string[]
添加所需数量的列名称以及相应的值以签入单独的 object[]
。查询检查 datatable
,如果找到匹配,则该方法返回 true
,如果没有,则返回 false
。
如果您需要“OR”或其他复杂性,您可以使用Expression类。 检查这个答案: https://stackoverflow.com/a/78770748/5063739
public IOrderedQueryable<ProductDetail> GetProductList(string productGroupName, string productTypeName, Dictionary<string,List<string>> filterDictionary)
{
var q = db.ProductDetail.Where(BuildFilter(productGroupName,productTypeName)).Orderby(c=>c.ProductTypeName);
return q;
}
private static Expression<Func<ProductDetail, bool>> BuildFilter(string productGroupName, string productTypeName)
{
var p = Expression.Parameter(typeof(ProductDetail));
return Expression.Lambda<Func<ProductDetail, bool>>(
Expression.AndAlso(
Expression.Equal(
Expression.Property(p, "productGroupName"),
Expression.Constant(productGroupName)
),
Expression.OrElse(
Expression.Equal(
Expression.Property(p, "productTypeName"),
Expression.Constant(productTypeName.ToLower())
),
Expression.Equal(
Expression.Property(p, "productTypeName"),
Expression.Constant(productTypeName)
)
)
),
p
);
}
这相当于
c.ProductGroupName == productGroupName
&& (c.ProductTypeName == productTypeName.toLower()
|| c.ProductTypeName == productTypeName
)