我有一个引用自己的类,如下所示:
public class Person
{
int Id { get; set; }
string Name { get; set; }
DateTime CreatedOn { get; set; }
Person Parent { get; set; }
ICollection<Person> Children { get; set; }
}
我需要的是一个Linq查询,它将返回一个列表,该列表仅包含具有子项的记录的最新记录(基于“CreatedOn”),或者为那些不具有子项的记录返回父本身。该查询还需要对整个“族”应用一些过滤器。例如,如果我使用名称“John”进行过滤,并且只有父级的名字是“John”,我仍然需要检索其最近的孩子。
任何帮助都将不胜感激。
答案 0 :(得分:1)
你可以这样做:
var results = db.Persons.Where(p => p.Name == "John")
.Select(p => p.Children.OrderByDescending(c => c.CreadedOn).FirstOrDefault() ?? p);
或者如果您更喜欢查询语法
var results =
from p in db.Persons
where p.Name == "John"
select(p => p.Children.OrderByDescending(c => c.CreadedOn).FirstOrDefault() ?? p);
生成的sql将如下所示:
SELECT
(CASE
WHEN NOT (EXISTS(
SELECT TOP (1) NULL AS [EMPTY]
FROM [Person] AS [t2]
WHERE [t2].[ParentId] = [t0].[Id]
ORDER BY [t2].[Id] DESC
)) THEN 1
WHEN NOT NOT (EXISTS(
SELECT TOP (1) NULL AS [EMPTY]
FROM [Person] AS [t2]
WHERE [t2].[ParentId] = [t0].[Id]
ORDER BY [t2].[Id] DESC
)) THEN 0
ELSE NULL
END) AS [value], [t0].[Id], [t0].[ParentId], [t0].[Name], [t0].[CreatedOn]
FROM [Parent] AS [t0]
WHERE [t0].[Name] = @p0
GO
答案 1 :(得分:1)
对于Linq-To-Entities不确定,Linq-To-Objects应该可以工作:
var lastChildOfJohn = persons.Where(p => p.Name == "John" && p.Children.Any())
.SelectMany(p => p.Children)
.OrderByDescending(p => p.CreatedOn)
.FirstOrDefault();
答案 2 :(得分:0)
你应该使用 Stack 对象,因为它们可以在LIFO(后进先出基础)上工作。
以下是MSDN的链接: -
http://msdn.microsoft.com/en-us/library/system.collections.stack.aspx
对我来说,这正是你想要做的。
如果使用Stack.Peek方法,它将自动返回放置在堆栈上的最后一个对象。
您还可以使用Pop返回最新的对象,然后将其从堆栈中删除。
Peek返回堆栈顶部的对象而不删除它。
Pop删除并返回堆栈顶部的对象。
答案 3 :(得分:0)
好吧,所以经过大量的搔抓和反复试验,这是我提出的查询(分为3行以便于阅读):
var query = db.People.AsQueryable();
query = !string.IsNullOrEmpty(name) ? query.Where(x => x.Name.Contains(name) || x.Ocorrencias.Any(y => y.Name.Contains(name))) : query;
query = query.Select(p => (p.Children.Count == 0 && p.Parent == null) ? p : p.Children.OrderByDescending(c => c.CreatedOn).FirstOrDefault()).Where(x => x != null);
这将返回我需要的内容:将过滤器应用于父级和子级的对象列表(如果有)。如果有孩子,只返回最近的孩子。我不得不在末尾添加“Where x!= null”来过滤掉“FirstOrDefault”返回的空对象。
我打算将p.s.w.g和Tim的评论标记为答案,因为他们让我走上了正确的轨道来解决这个问题,但显然我只能将一条评论标记为答案。谢谢你的帮助!