Reputation: 73
I am trying write linq lambda select to get all records from database that has a number which is in any of the specific intervals from other list or database table. Lets say i have a table "SOURCE"
+------+------+-------+------+------+
| Col1 | Col2 | reqNr | col5 | col6 |
+------+------+-------+------+------+
| x | x | 9 | x | x |
| x | x | 14 | x | x |
| x | x | 19 | x | x |
| x | x | 24 | x | x |
+------+------+-------+------+------+
and I have already selected table "INTERVALS"
+------+----+
| from | to |
+------+----+
| 1 | 3 |
| 5 | 10 |
| 15 | 30 |
+------+----+
to object list "intervalList" in c#.
How can write ".Where()" part in linq sql statement to get all records from "SOURCE" that has "ReqNr" column value which falls in any of the intervals from "intervalList" list.
For example: .where(w => intervalList.any(w.ReqNr > intervalList.from && w.ReqNr < intervalList.to))
Upvotes: 3
Views: 700
Reputation: 27861
As I understand your question, you need the query to be executed on the database side, and the intervals
list is a list in memory.
You need a SQL query that looks like this:
SELECT * FROM SOURCE WHERE
((1 < reqNr) AND (3 > reqNr))
OR ((5 < reqNr) AND (10 > reqNr))
OR ((15 < reqNr) AND (30 > reqNr))
As you can see, the query itself is dynamic. The number and content of the OR conditions depend on the intervals list (which is an in memory list).
To generate such a dynamic query you need to build an Expression<Func<Item,bool>>
dynamically and pass it to the Where
method. (Item
is the name of the entity of the Source table).
You can use LinqKit to create such dynamic expression like this:
Expression<Func<Item, bool>> condition =
intervals
.Select(
interval =>
(Expression<Func<Item, bool>>)
(x => interval.From < x.reqNr && interval.To > x.reqNr))
.Aggregate(LinqKit.PredicateBuilder.Or);
var result = context.SourceTable
.Where(condition)
.ToList();
By the way, this solution is complex only because the intervals list is in memory. An easier solution is to query the database directly using the intervals stored in the database like this:
var result =
context.SourceTable
.Where(x =>
context.Intervals.Any(interval =>
interval.From < x.reqNr && interval.To > x.reqNr))
.ToList();
Upvotes: 1
Reputation: 2139
You can do this:
var result = iRec
.Where(r => intervalList.Any(i => i.From <= r.reqNr && i.To >= r.reqNr))
.ToList();
You can check it here.
Upvotes: 2
Reputation: 6766
Apply where and Any as inner predicate to where method like below:
var result = SOURCE
.Where(d => INTERVALS.Any(e => e.from<d.reqNr && e.to>d.reqNr))
.ToList();
Upvotes: 1