Linq从另一个间隔列表中选择任何间隔中的所有数字

时间:2017-06-21 10:08:44

标签: c# sql .net linq lambda

我正在尝试编写linq lambda select来获取数据库中的所有记录,这些记录的编号与其他列表或数据库表中的任何特定时间间隔相同。让我们说我有一张桌子&#34; SOURCE&#34; +------+------+-------+------+------+ | 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 | +------+------+-------+------+------+ 我已经选择了表格&#34; INTERVALS&#34; +------+----+ | from | to | +------+----+ | 1 | 3 | | 5 | 10 | | 15 | 30 | +------+----+ 对象列表&#34; intervalList&#34;在c#中。 如何写&#34; .Where()&#34;参与linq sql语句以获取来自&#34; SOURCE&#34;的所有记录。那有&#34; ReqNr&#34;列值的任何间隔来自&#34; intervalList&#34;名单。 例如:.where(w => intervalList.any(w.ReqNr > intervalList.from && w.ReqNr < intervalList.to))

3 个答案:

答案 0 :(得分:1)

将where和Any作为内部谓词应用于以下方法:

var result = SOURCE
  .Where(d => INTERVALS.Any(e => e.from<d.reqNr && e.to>d.reqNr))
  .ToList();

答案 1 :(得分:1)

你可以这样做:

var result = iRec
  .Where(r => intervalList.Any(i => i.From <= r.reqNr && i.To >= r.reqNr))
  .ToList();

您可以查看here

答案 2 :(得分:1)

据我所知,您需要在数据库端执行查询,intervals列表是内存中的列表。

您需要一个如下所示的SQL查询:

SELECT * FROM SOURCE WHERE 
    ((1 < reqNr) AND (3 > reqNr))
    OR ((5 < reqNr) AND (10 > reqNr))
    OR ((15 < reqNr) AND (30 > reqNr))

如您所见,查询本身是动态的。 OR条件的数量和内容取决于间隔列表(在内存列表中)。

要生成此类动态查询,您需要动态构建Expression<Func<Item,bool>>并将其传递给Where方法。 (Item是Source表的实体名称。)

您可以使用LinqKit创建如下动态表达式:

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();

顺便说一句,这个解决方案很复杂,因为区间列表在内存中。更简单的解决方案是使用存储在数据库中的间隔直接查询数据库,如下所示:

var result =
    context.SourceTable
        .Where(x =>
            context.Intervals.Any(interval =>
                interval.From < x.reqNr && interval.To > x.reqNr))
        .ToList();