开发者

Problem with linq query

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


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.


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜