linq查询出现问题

本文关键字:问题 查询 linq | 更新日期: 2023-09-27 18:06:47

我有一个自引用表"Product",其结构如下(其中D = Draft, a = Approved)

ID   ParentID  Status  Name
---------------------------
1    NULL      A       Foo
2    1         A       Foo2
3    NULL      D       Bar
4    1         D       Foo3

行可以是"new"(其中ParentID == null),也可以是现有行的一个版本。因此,我们可以从表中看到,条目"Foo"有3个版本,而条目"Bar"只有1个版本。

我需要一种方法,根据用户是否只能看到"已批准"的项目或也能够看到"草案",返回每个项目的最新版本。例如

可以看到"D"的用户会:

3    NULL    D
4    1       D

"Foo"answers"Bar"的"最新"行。

可以看到"A"的用户将有:

2    1       A

ie。只有"批准"的版本。

提前感谢,

何塞

linq查询出现问题

下面是为您工作的Linq查询:

bool hasDraftAccess = false;
var query = DataContext.Records.AsQueryable();
if (!hasDraftAccess) {
    query = query.Where(r => r.Status == 'A');
}
var seriesQuery = query.Select(r => new { Record = r, SeriesID = r.ParentID ?? r.ID });
var latestQuery = seriesQuery.GroupBy(s => s.SeriesID).Select(g => g.OrderByDescending(s => s.Record.ID).First());
var resultsQuery = latestQuery.Select(s => s.Record);
var results = resultsQuery.ToArray();

情况如下:

  1. 首先,添加WHERE子句来过滤掉用户没有权限访问的草稿记录
  2. 然后添加一个名为'SeriesID'的伪列,将所有相关版本分组到该列中。也就是说,可以很容易地对父级和相关子级进行分组。
  3. 将相关记录分组,然后选择最近的记录
  4. 从匿名类型中选择Linq实体,使其可更新

我应该注意到,如果你有能力改变你的数据模式,你应该考虑添加一个名为InsertDate的列或类似的东西。现在我假设具有最高ID的记录是最新的。通常最好添加一个DateTime字段并在其上排序。

我很抱歉,这实际上并没有使用Linq语法——我更喜欢流畅的编码风格——但如果你喜欢的话,它可以很容易地翻译成Linq语法。

完全未经测试-但这样的东西可能工作,如果我理解正确的问题。

可以看到批准

context.Table.Where(p => p.Status == "A")

可以看到批准和草案

context.Table.Where(p => p.Status == "D" || (p.Status == "A" && !context.Table.Any(q => q.Status == "D" && q.Parent == p.Parent)))