我有一个自我引用的类。 IdModuloPai 是指向其父级的键, ModulosFilhos 是该对象的子级。
我有一个属性 Profundidade ,它以递归方式计算该对象的深度。
另一个重要的属性是 Ordem 。它保存用户在该范围内定义的所需顺序。
Id Nome IdModuloPai Ordem Profundidade OrdemGlobal
1 Root [NULL] 0 0 0
2 Users 1 0 1 1
3 Administration 2 0 2 2
4 Logs 2 1 2 3
5 Customers 1 0 1 4
6 Orders 5 0 2 5
请看这个示例表。
我正在尝试创建一个类似于Profundidade的函数,它计算了它的全球位置。我正在努力获得最后一栏 OrdemGlobal 。然后,我可以通过OrdemGlobal订购对象,它将在我需要的每个地方以相同的方式出现。
根据此表,正确的位置是
Root
+Users
+Administration
+Logs
+Customers
+Orders
在日志之前查看管理层是否存在因为管理具有Ordem = 0且Logs具有Ordem = 1
我怎样才能达到理想的行为?
我的班级代码如下
public class ModuloModel
{
public int Id { get; set; }
public string Nome { get; set; }
public int Ordem { get; set; }
public virtual int Profundidade {
get
{
return GetDepth(this);
}
}
public int? IdModuloPai { get; set; }
public virtual ModuloModel ModuloPai { get; set; }
public virtual ICollection<ModuloModel> ModulosFilhos { get; set; }
private int GetDepth(ModuloModel moduloModel)
{
if (moduloModel == null) return 0;
if (moduloModel.IdModuloPai == null) return 0;
return GetDepth(moduloModel.ModuloPai) + 1;
}
}
编辑:改进问题
我尝试过像
这样的东西 public virtual int OrdemGlobal
{
get
{
return GetGlobalOrder(this);
}
}
private int GetGlobalOrder(ModuloModel moduloModel)
{
if (moduloModel == null) return 0;
if (moduloModel.ModuloPai == null) return 0;
int smallerSiblings = moduloModel.ModuloPai.ModulosFilhos.Where(x => x.Ordem < moduloModel.Ordem).Count();
return (GetGlobalOrder(moduloModel.ModuloPai) + smallerSiblings + 1;
}
但这很困惑,并没有返回所需的信息。
答案 0 :(得分:1)
这是IComparer<ModuloModel>
,可按您想要的顺序排序。
public class ModuloModelComparer : Comparer<ModuloModel>
{
public override int Compare(ModuloModel x, ModuloModel y)
{
//They are the same node.
if (x.Equals(y))
return 0;
//Cache the values so we don't need to do the GetDepth call extra times
var xProfundidade = x.Profundidade;
var yProfundidade = y.Profundidade;
//Find the shared parent
if (xProfundidade > yProfundidade)
{
//x is a child of y
if (x.ModuloPai.Equals(y))
return 1;
return Compare(x.ModuloPai, y);
}
else if (yProfundidade > xProfundidade)
{
//y is a child of x
if (x.Equals(y.ModuloPai))
return -1;
return Compare(x, y.ModuloPai);
}
else
{
//They both share a parent but are not the same node, just compare on Ordem.
if (x.ModuloPai.Equals(y.ModuloPai))
return x.Ordem.CompareTo(y.Ordem);
//They are the same level but have diffrent parents, go up a layer
return Compare(x.ModuloPai, y.ModuloPai);
}
}
}
这是一个使用它的测试程序
class Test
{
public static void Main()
{
var root = CreateModel(1, "Root", null, 0);
var users = CreateModel(2, "Users", root, 0);
var administration = CreateModel(3, "Administration", users, 0);
var logs = CreateModel(4, "Logs", users, 1);
var customers = CreateModel(5, "Customers", root, 0);
var orders = CreateModel(6, "Orders", customers, 0);
List<ModuloModel> list = new List<ModuloModel> {root, users, administration, logs, customers, orders};
list.Sort(new ModuloModelComparer());
foreach (var moduloModel in list)
{
Console.WriteLine(moduloModel.Nome);
}
Console.ReadLine();
}
private static ModuloModel CreateModel(int id, string Nome, ModuloModel moduloPai, int ordem)
{
var model = new ModuloModel {Id = id, Nome = Nome, IdModuloPai = moduloPai?.Id, ModuloPai = moduloPai, ModulosFilhos = new HashSet<ModuloModel>(), Ordem = ordem};
moduloPai?.ModulosFilhos.Add(model);
return model;
}
}
希望这足以让你走上正轨。
答案 1 :(得分:0)
为什么不返回
return this.Ordem;
聚合根在哪里?这个类指的是它自己,所以它必须知道它有什么Ordem值。它不知道它上面的任何东西,只有它的孩子。