C# Linq查询难题
如果我有一个具有父子关系的对象,其Id和ParentId表示记录的唯一Id和记录的父Id 我需要一个查询,该查询将查询对象列表并返回每个项的关系根的路径,即path=AllTheParentNames\Name 在此方面的任何帮助都将不胜感激 肌体 整数Id 智力?父ID 字符串名C# Linq查询难题,c#,linq,C#,Linq,如果我有一个具有父子关系的对象,其Id和ParentId表示记录的唯一Id和记录的父Id 我需要一个查询,该查询将查询对象列表并返回每个项的关系根的路径,即path=AllTheParentNames\Name 在此方面的任何帮助都将不胜感激 肌体 整数Id 智力?父ID 字符串名 字符串路径我相信这将为您提供预期的结果 Func<int?, string> GetParents = null; List<URClass> lstRoot
字符串路径我相信这将为您提供预期的结果
Func<int?, string> GetParents = null;
List<URClass> lstRoot = new List<URClass>();
lstRoot.Add(new URClass() { Id = 1, Name = "a", ParentId = null, Path = "1" });
lstRoot.Add(new URClass() { Id = 2, Name = "b", ParentId = 1, Path = "1" });
lstRoot.Add(new URClass() { Id = 3, Name = "c", ParentId = 2, Path = "1" });
lstRoot.Add(new URClass() { Id = 4, Name = "d", ParentId = 3, Path = "1" });
lstRoot.Add(new URClass() { Id = 5, Name = "e", ParentId = 4, Path = "1" });
GetParents = i =>
{
var str = string.Empty;
var outt = lstRoot.Where(x => x.Id == i).Select(x=>new {x.Name,x.ParentId });
foreach (var lst in outt)
{
str += lst.Name;
if (lst.ParentId != null)
{
var outts = GetParents(lst.ParentId);
str += "," + outts;
}
}
return str;
};
var ks = from p in lstRoot
join q in lstRoot on p.Id equals q.ParentId
select new { q.Id, parentName = p.Name, parentid=p.Id, gpid=p.ParentId };
List<string> RelationShip = new List<string>();
foreach (var lst in ks)
{
var str = lst.parentName;
if (lst.gpid != null)
{
var prnt = GetParents(lst.gpid);
if (prnt != null)
str += "," + prnt;
}
str += "/" + lst.Id;
RelationShip.Add(str);
}
foreach (var ret in RelationShip)
Console.WriteLine(ret);
输出将是
a/2
b、 a/3
c、 b,a/4
d、 c、b、a/5
我相信这会给你预期的结果
Func<int?, string> GetParents = null;
List<URClass> lstRoot = new List<URClass>();
lstRoot.Add(new URClass() { Id = 1, Name = "a", ParentId = null, Path = "1" });
lstRoot.Add(new URClass() { Id = 2, Name = "b", ParentId = 1, Path = "1" });
lstRoot.Add(new URClass() { Id = 3, Name = "c", ParentId = 2, Path = "1" });
lstRoot.Add(new URClass() { Id = 4, Name = "d", ParentId = 3, Path = "1" });
lstRoot.Add(new URClass() { Id = 5, Name = "e", ParentId = 4, Path = "1" });
GetParents = i =>
{
var str = string.Empty;
var outt = lstRoot.Where(x => x.Id == i).Select(x=>new {x.Name,x.ParentId });
foreach (var lst in outt)
{
str += lst.Name;
if (lst.ParentId != null)
{
var outts = GetParents(lst.ParentId);
str += "," + outts;
}
}
return str;
};
var ks = from p in lstRoot
join q in lstRoot on p.Id equals q.ParentId
select new { q.Id, parentName = p.Name, parentid=p.Id, gpid=p.ParentId };
List<string> RelationShip = new List<string>();
foreach (var lst in ks)
{
var str = lst.parentName;
if (lst.gpid != null)
{
var prnt = GetParents(lst.gpid);
if (prnt != null)
str += "," + prnt;
}
str += "/" + lst.Id;
RelationShip.Add(str);
}
foreach (var ret in RelationShip)
Console.WriteLine(ret);
输出将是
a/2
b、 a/3
c、 b,a/4
d、 c、b、a/5
这是预期的结果吗
class A
{
public int Id;
public int? ParentId;
public string Name;
public static Func<T1, T2> Fix<T1, T2>(Func<Func<T1, T2>, Func<T1, T2>> f)
{
return f(x => Fix(f)(x));
}
public static string[] GetPaths(A[] array)
{
return array.Select(
Fix<A, string>(self => x => x.ParentId != null ? self(array.First(a => a.Id == x.ParentId.Value)) + "\\" + x.Name : x.Name)
).ToArray();
}
}
在单个查询中不可能不使用递归,因为数组上的每个聚合可能有助于模拟递归,但它很愚蠢
修复-这是预期结果吗
class A
{
public int Id;
public int? ParentId;
public string Name;
public static Func<T1, T2> Fix<T1, T2>(Func<Func<T1, T2>, Func<T1, T2>> f)
{
return f(x => Fix(f)(x));
}
public static string[] GetPaths(A[] array)
{
return array.Select(
Fix<A, string>(self => x => x.ParentId != null ? self(array.First(a => a.Id == x.ParentId.Value)) + "\\" + x.Name : x.Name)
).ToArray();
}
}
在单个查询中不可能不使用递归,因为数组上的每个聚合可能有助于模拟递归,但它很愚蠢
Fix-是第一个节点,假设您有一个节点。您希望获得根目录的路径 让我们将根的路径表示为一系列节点 我们可以构建这个函数,编写一个方法,该方法接受一个项和一个函数,该函数标识下一个项,并返回序列
public static IEnumerable<T> Path(T item, Func<T, T> nextItem) where T : class
{
T current = item;
while(current != null)
{
yield return current;
current = nextItem(current);
}
}
等等
有意义吗?首先,假设您有一个节点。您希望获得根目录的路径 让我们将根的路径表示为一系列节点 我们可以构建这个函数,编写一个方法,该方法接受一个项和一个函数,该函数标识下一个项,并返回序列
public static IEnumerable<T> Path(T item, Func<T, T> nextItem) where T : class
{
T current = item;
while(current != null)
{
yield return current;
current = nextItem(current);
}
}
等等
有意义吗?为什么你认为这是家庭作业?即使那是什么事?除非是建设性的,否则为什么要说。为什么你认为这是家庭作业?即使那是什么事?除非是建设性的,否则为什么要说任何话。这看起来像是很多代码来实现我的期望。@Burt,是的,当然。。但它给出了预期的结果。。我也在学习lambdas&linq,这就是原因。。无论如何,我现在正在重构代码:看起来有很多代码可以实现我的期望。@Burt,是的,当然。。但它给出了预期的结果。。我也在学习lambdas&linq,这就是原因。。无论如何,我现在正在重构代码: