linq查询问题

时间:2011-08-28 17:38:57

标签: c# linq linq-to-sql

我有一个自引用表“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”和“Bar”的“最新”行。

可以看到“A”的用户将拥有:

2    1       A

即。只有“已批准”的版本。

提前致谢,

2 个答案:

答案 0 :(得分:0)

以下是适合您的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实体,以便它可以更新
  5. 我应该注意,如果您能够更改数据模式,则应考虑添加名为InsertDate的列或其他类似的效果。现在我假设任何具有最高ID的记录都是最新的。通常最好添加一个DateTime字段并对其进行排序。

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

答案 1 :(得分:-1)

完全未经测试 - 但如果我正确理解了这个问题,那么这样的事情可能有用。

可以看到已批准的

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