I want to search my db with different keys. According to the input, there may be 1 key to 10 keys. Is there a way to add OR/AND clauses to my Linq query dynamically?
You can use the extension methods of 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 })
You can do something like this. Remember it may casue some overhead
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)
For AND clauses it is simple:
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 {....});
For OR you will need to use Expressions
or try LinqKit and its predicates :
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 {....});
You could try an .All clause to check all the keys:
where keys.All(key => feed.content.contains(key))
I wanted to provide an example of how @mellamokb's answer worked for my scenario to possibly help out anyone needing a fairly dynamic linq
query.
In my example I have simply made an extension of the datatable
class so I can check if a row of data exists as it stands in the database so no SQL
primary key exceptions are thrown.
/// <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);
}
This method allows you to add as many column names as you require to a string[]
along with the corresponding values to check in a separate object[]
. The query checks against the datatable
and if it finds a match the method returns true
and if not it returns false
.