linq查询的问题

发布于 2024-12-02 02:25:40 字数 602 浏览 0 评论 0原文

我有一个自引用表“产品”,其结构如下(其中 D = 草稿且 A = 已批准)

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

行可以是“新”行(其中 ParentID == null),也可以是现有行的版本。所以我们从表中可以看到,“Foo”项有 3 个版本,而“Bar”只有 1 个版本。

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

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

3    NULL    D
4    1       D

“Foo”和“Bar”的“最新”行。

可以看到“A”的用户会:

2    1       A

即。仅“已批准”版本。

预先感谢,

何塞

I have a self referencing table "Product" with the following structure (where D = Draft and A = Approved)

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

A row can either be "new" (where ParentID == null) or can be a version of an existing row. So we can see from the table that there are 3 versions for the item "Foo" and only 1 for "Bar".

I need a way of returning the latest versions of each item based on whether the user is able to see only "Approved" items or is able to see "Draft" as well. So for example

Users who can see "D" would have:

3    NULL    D
4    1       D

The "latest" row for "Foo" and "Bar".

Users who can see "A" would have:

2    1       A

ie. only the "Approved" versions.

Thanks in advance,

Jose

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

莫相离 2024-12-09 02:25:40

这是应该适合您的 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 最高的记录是最新的。通常最好添加一个日期时间字段并对其进行排序。

我很抱歉这实际上并没有使用 Linq 语法——我更喜欢流畅的编码风格——但如果您愿意的话,它可以很容易地转换为 Linq 语法。

Here is the Linq query that should work for you:

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

Here's what's happening:

  1. First, add a WHERE clause to filter out draft records if the user doesn't have access to them
  2. Then add a pseudo column called 'SeriesID' that groups all the related versions into that one column. That is, make it easy to group parent and related children.
  3. Group the related records and then pick whichever record is most recent
  4. Select the Linq Entity from the anonymous type so that it is updatable

I should note that if you have the ability to change your data schema you should consider adding a column called InsertDate or something to that effect. Right now I am assuming that whatever record has the highest ID is the latest. It is often better to add a DateTime field and sort on that instead.

I apologize that this isn't actually using Linq syntax--I prefer fluent coding styles--but it could be easily translated to Linq syntax if you preferred it.

§对你不离不弃 2024-12-09 02:25:40

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

可以看到已批准

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

Totally untested - but something like this might work, if I've understood the question correctly.

Can see approved

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

Can see approved and draft

context.Table.Where(p => p.Status == "D" || (p.Status == "A" && !context.Table.Any(q => q.Status == "D" && q.Parent == p.Parent)))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文