Lambda/Linq with Contains criteria for multiple keywords
Answering for my and others' reference.
var newList = MainList.Where(m => keywords.Any(k => m.Comments.Contains(k))).ToList();
LINQ with non-lambda for Any Contains
It's not clear what good you believe the from wor in words select wor
is doing - it's really not helping you at all.
It's also not clear why you don't want to use a lambda expression. The obvious approach is:
bool hasBelieve = words.Any(x => x.Contains("believe"));
Note that this isn't checking whether the list of words has the word "believe" in - it's checking whether the list of words has any word containing "believe". So "believer" would be fine. If you just want to check whether the list contains believe
you can just use:
bool hasBelieve = words.Contains("believe");
EDIT: If you really want to do it without a lambda expression, you'll need to basically fake the work that the lambda expression (or anonymous method) does for you:
public class ContainsPredicate
{
private readonly string target;
public ContainsPredicate(string target)
{
this.target = target;
}
public bool Apply(string input)
{
return input.Contains(target);
}
}
Then you can use:
Func<string, bool> predicate = new ContainsPredicate("believe");
bool hasBelieve = words.Any(predicate);
Obviously you really don't want to do that though...
EDIT: Of course you could use:
var allBelieve = from word in words
where word.Contains("believe")
select word;
bool hasBelieve = allBelieve.Any();
But that's pretty ugly too - I'd definitely use the lambda expression.
Lambda or Linq method to search multiple parameters
If I understand correctly, you don't want to filter if the value of the parameters is 0? If so, two solutions:
Check if the parameter is equal to 0 in your condition:
var lstJobs = dx.GetAllJobs().Where(x =>
(SecLink == 0 || x.SectorLink.Equals(SecLink))
&& (LocLink == 0 || x.LocationLink.Equals(LocLink))
&& (IndLink == 0 || x.IndustryLink.Equals(IndLink))
&& (VacLink == 0 || x.VacancyTypeLink.Equals(VacLink))
&& x.JobName.Contains(keyword)).ToList();Linq goodness, dynamically construct your query:
var query = dx.GetAllJobs().Where(x => x.JobName.Contains(keyword));
if (SecLink != 0)
{
query = query.Where(x => x.SectorLink.Equals(SecLink));
}
if (LocLink != 0)
{
query = query.Where(x => x.LocationLink.Equals(LocLink));
}
if (IndLink != 0)
{
query = query.Where(x => x.IndustryLink.Equals(IndLink));
}
if (VacLink != 0)
{
query = query.Where(x => x.VacancyTypeLink.Equals(VacLink));
}
var lstJobs = query.ToList();
Is there any way to optimize this LINQ where clause that searches for multiple keywords on multiple columns?
The real performance hit is that this kind of query is tough to optimize. You want to find substrings, which by default are not indexable.
From a purely L2S perspective there isn't much you can do. But if you can enable Full-text search, you'll have much better tools at your disposal to speed up your query.
See this Stack Overflow post for more info.
Filter query by multiple parameters from the list of objects
I had this issue earlier and here how I fixed it
You have two options in this case
1- Filter based on the ids
var res1 = dbcontext.CustomerPurchases
.Where(p => filters.Select(c=>c.PurchaseId).Contains(p.PurchaseId))
.Where(p => filters.Select(c => c.CustomerId).Contains(p.CustomerId));
2- Use contains
var resq = await dbcontext.CustomerPurchases
.Where(p=> filters.Contains(new Filter { CustomerId = p.CustomerId,PurchaseId = p.PurchaseId }))
.ToListAsync();
but if you run this one you won't get any result unless you implement IEquatable
So your Filter
class will look like this
public class Filter : IEquatable<Filter>
{
public int CustomerId;
public int PurchaseId;
public bool Equals(Filter? other)
{
return this.PurchaseId == other.PurchaseId &&
this.CustomerId == other.CustomerId;
}
}
Here is the full code of both ways
var options = new DbContextOptionsBuilder<ApplicationDBContext>()
.UseInMemoryDatabase("test")
.Options;
var dbcontext = new ApplicationDBContext(options);
await dbcontext.CustomerPurchases.AddAsync(new CustomerPurchase { CustomerId = 1,PurchaseId = 1,Cost = 10 });
await dbcontext.CustomerPurchases.AddAsync(new CustomerPurchase { CustomerId = 1, PurchaseId = 2, Cost = 10 });
await dbcontext.CustomerPurchases.AddAsync(new CustomerPurchase { CustomerId = 1, PurchaseId = 3, Cost = 10 });
await dbcontext.CustomerPurchases.AddAsync(new CustomerPurchase { CustomerId = 2, PurchaseId = 2, Cost = 10 });
await dbcontext.SaveChangesAsync();
var filters = new List<Filter>();
filters.Add(new Filter { CustomerId = 1, PurchaseId = 2 });
filters.Add(new Filter { CustomerId = 2, PurchaseId = 2 });
var resq = await dbcontext.CustomerPurchases
.Where(p=> filters.Contains(new Filter { CustomerId = p.CustomerId,PurchaseId = p.PurchaseId }))
.ToListAsync();
foreach (var item in resq)
{
Console.WriteLine($" CustomerId : {item.CustomerId} , PurchaseId : {item.PurchaseId} Cost : {item.Cost}");
}
var res1 = dbcontext.CustomerPurchases
.Where(p => filters.Select(c=>c.PurchaseId).Contains(p.PurchaseId))
.Where(p => filters.Select(c => c.CustomerId).Contains(p.CustomerId));
var res = await res1.ToListAsync();
Console.WriteLine("===========================================================");
foreach (var item in res)
{
Console.WriteLine($" CustomerId : {item.CustomerId} , PurchaseId : {item.PurchaseId} Cost : {item.Cost}");
}
and the running code
Update
After changed to SQL server I still got the error so option 2 is not an option when running on SQL server
But I found another solution where I am able to build the where clause based on the list of filters that I have
I found this PredicateBuilder
and here is the code using predicate builder
var whereclause = PredicateBuilder.False<CustomerPurchase>();
foreach (var filterrow in filters)
{
whereclause = whereclause.Or(c => c.CustomerId == filterrow.CustomerId && c.PurchaseId == filterrow.PurchaseId);
}
var resqq = dbcontext.CustomerPurchases.Where(whereclause);
var resq = await resqq.ToListAsync();
foreach (var item in resq)
{
Console.WriteLine($" CustomerId : {item.CustomerId} , PurchaseId : {item.PurchaseId} Cost : {item.Cost}");
}
That will build the query which will be translated by sql to the following statement
DECLARE @__filterrow_CustomerId_0 int = 1;
DECLARE @__filterrow_PurchaseId_1 int = 2;
DECLARE @__filterrow_CustomerId_2 int = 2;
DECLARE @__filterrow_PurchaseId_3 int = 2;
SELECT [c].[PurchaseId], [c].[CustomerId]
FROM [dbo].[CustomerPurchase] AS [c]
WHERE (([c].[CustomerId] = @__filterrow_CustomerId_0) AND ([c].[PurchaseId] = @__filterrow_PurchaseId_1))
OR
(([c].[CustomerId] = @__filterrow_CustomerId_2) AND ([c].[PurchaseId] = @__filterrow_PurchaseId_3))
Here is the full class of PredicateBuyilder
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
}
}
I hope that answer your question !!
how use like in sql on linq c#
EF Core cannot use Any
with local collections (with small excpetion), only Contains
is supported.
I would suggest to use function FilterByItems. And use in query:
string[] DATE_Group = { "2020", "2021" }; //changing values
var query = _context.c10
.FilterByItems(DATE_Group, (u, s) => u.ON_DATE.Contains(s), true)
.Select(u => new
{
User_NumberID = u.User_NumberID.ToString()
})
.ToList();
Adding LINQ Where && condition in a foreach loop
Enumerable.Contains
is supported with collections:
string providedpostCode = "A41666";
string[] providedPostCodes = Enumerable.Range(0, providedpostCode.Length)
.Select(ix => providedpostCode.Substring(0, ix + 1))
.ToArray();
bool isSupported = !postcodeExclusionArray
.Any(x => x.CustomerId == 2 && providedPostCodes.Contains(x.Postocde));
Not sure about the logic, if you need Any
or !Any
.
Query where multiple columns have to match a value set simultaneously in EF Core
I'd be inclined to build a dynamic Expression<Func<MyTableRow, bool>>
to represent the filter.
var p = Expression.Parameter(typeof(MyTableRow), "dbItem");
var parts = new List<Expression>();
foreach (var set in typeVersionSets)
{
var typeIdValue = Expression.Property(p, nameof(MyTableRow.TypeId));
var typeIdTarget = Expression.Constant(set.Type);
var typeIdTest = Expression.Equal(typeIdValue, typeIdTarget);
var versionIdValue = Expression.Property(p, nameof(MyTableRow.VersionId));
var versionIdTarget = Expression.Constant(set.Version);
var versionIdTest = Expression.Equal(versionIdValue, versionIdTarget);
var part = Expression.AndAlso(typeIdTest, versionIdTest);
parts.Add(part);
}
var body = parts.Aggregate(Expression.OrElse);
var filter = Expression.Lambda<Func<MyTableRow, bool>>(body, p);
List<MyTableRow> MyResult = await dbContext.MyTable
.Where(filter)
.ToListAsync()
Expression Trees (C#) | Microsoft Docs
Related Topics
How to Autheticate to Ibm Mq C# with Tls-Certificate
Can You Develop Linux Applications with Xamarin
Why Filesystemwatcher Doesn't Work in Linux Container Watching Windows Volume
.Net Core MAChine Key Alternative for Webfarm
C# Execute a Terminal Command in Linux
Mono High Resolution Timer (On Linux)
Change Current Linux User in a C# Application Running with Mono
Does Mono Support System.Drawing and System.Drawing.Printing
Mono Shared Library Under Linux Location
How to Create a Navigation Menu in Dotnet Application
Globally Catch Exceptions in a Wpf Application
"The Remote Certificate Is Invalid According to the Validation Procedure." Using Gmail Smtp Server
What Guarantees Are There on the Run-Time Complexity (Big-O) of Linq Methods
Get Name of Property as a String
Differencebetween Debug and Release in Visual Studio
How to Deserialize Xml into List<T>
How to Convert Seconds into (Hour:Minutes:Seconds:Milliseconds) Time