[英]Recursive linq query
I have the following object structure. 我有以下对象结构。
public class Study
{
public Guid? PreviousStudyVersionId { get; set; }
public Guid StudyId { get; set; }
//Other members left for brevity
}
It is persisted using entity Framework code first. 它首先使用实体框架代码持久化。
It results in a table like this 它产生一个这样的表格
PreviousStudyVersionId StudyId
EF90F9DC-C588-4136-8AAE-A00E010CE87B E4315CFD-9638-4225-998E-A00E010CEEEC
NULL 1C965285-788A-4B67-9894-3D0D46949F11
1C965285-788A-4B67-9894-3D0D46949F11 7095B746-8D32-4CC5-80A9-A00E010CE0EA
7095B746-8D32-4CC5-80A9-A00E010CE0EA EF90F9DC-C588-4136-8AAE-A00E010CE87B
Now I want to query all studyId's recursive. 现在我想查询所有studyId的递归。 So I came up with the following solution:
所以我想出了以下解决方案:
So when I call the method in my repository GetAllStudyVersionIds(new Guid("7095B746-8D32-4CC5-80A9-A00E010CE0EA")) it returns me all 4 the studyId's. 因此,当我在我的存储库GetAllStudyVersionIds(new Guid(“7095B746-8D32-4CC5-80A9-A00E010CE0EA”))中调用该方法时,它将返回我所有的4个studyId。
public IEnumerable<Guid> GetAllStudyVersionIds(Guid studyId)
{
return SearchPairsForward(studyId).Select(s => s.Item1)
.Union(SearchPairsBackward(studyId).Select(s => s.Item1)).Distinct();
}
private IEnumerable<Tuple<Guid, Guid?>> SearchPairsForward(Guid studyId)
{
var result =
GetAll().Where(s => s.PreviousStudyVersionId == studyId).ToList()
.Select(s => new Tuple<Guid, Guid?>(s.StudyId, s.PreviousStudyVersionId));
result = result.Traverse(a => SearchPairsForward(a.Item1));
return result;
}
private IEnumerable<Tuple<Guid, Guid?>> SearchPairsBackward(Guid studyId)
{
var result = GetAll().Where(s => s.StudyId == studyId).ToList()
.Select(s => new Tuple<Guid, Guid?>(s.StudyId, s.PreviousStudyVersionId));
result = result.Traverse(a => a.Item2.HasValue ? SearchPairsBackward(a.Item2.Value) : Enumerable.Empty<Tuple<Guid, Guid?>>());
return result;
}
This is the implementetion of my extension method. 这是我的扩展方法的实现。
public static class MyExtensions
{
public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> fnRecurse)
{
foreach (var item in source)
{
yield return item;
var seqRecurse = fnRecurse(item);
if (seqRecurse == null) continue;
foreach (var itemRecurse in Traverse(seqRecurse, fnRecurse))
{
yield return itemRecurse;
}
}
}
}
Is there any way of moving this closer to the database (IQueryable) and optimize this code. 有没有办法让它更接近数据库(IQueryable)并优化此代码。
I have done this by making a recursive table function pulling all parent records based on id
and then creating a view to produce a list for each record and all the parents. 我通过制作递归表函数来完成此操作,该函数根据
id
拉出所有父记录,然后创建视图以生成每个记录和所有父项的列表。 Then I consume that in the EF model and associate to be able to use with LINQ. 然后我在EF模型中使用它并关联以便能够与LINQ一起使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.