我一直在浏览搜索系统并没有找到我的问题的答案,而这些问题是相似的,我甚至用它们中的一些来开始我已经碰到了砖墙。
我已经查看了这些问题
我有一个由nHibernate带回来的对象,名为Person,如下所示
public class Person : IPerson, IComparable<Person>{
// private properties
private int _id;
private string _name;
private Person _parent;
private IList<Person> _children;
private IList<Group> _groups;
// public properties
public virtual int id
{
get { return _id; }
set { _id = value; }
}
public virtual string name
{
get { return _name; }
set { _name= value; }
}
public virtual Person Parent
{
get { return _parent; }
set { _parent = value; }
}
public virtual IList<Person> Children
{
get { return _children; }
set { _children = value; }
}
public virtual IList<Group> Groups
{
get { return _groups; }
set { _groups = value; }
}
// constructor
public Person() {}
// this section I added after looking on SO
public virtual Int32 parentid
{
get {
if (_parent == null)
{
return _id;
} else {
return _parent.id;
}
}
}
public virtual Int32 CompareTo(Person obj)
{
if (this.id == obj.id)
return 0;
return this.parentid.CompareTo(obj.parentid);
}
}
然后在我的Dao中的一个方法,它返回一个组下数据库中所有Person对象的列表。不幸的是,它按照输入的顺序将它们带回来,我想将它们分类为父子关系。
i.e. (id,name,parent)
person 1 (1,"Alice",null)
person 2 (2,"Bob",1)
person 3 (3,"Charlie",null)
person 4 (4,"Dejgo",2) // child of a child
person 5 (5,"Edgar", null)
person 6 (6,"Florence", 3)
当我按照answer中提到的那样进行排序时,如此:
class PeopleBLL : IPeopleBLL {
// spring properties
private IGroupsBLL _groupsBLL;
private IPeopleDao _peopleDao;
// public properties where spring sets up the links to the other dao and bll methods
public IGroupsBLL {
set{_groupsBLL = value;}
}
public IPeopleDao {
set{_peopleDao= value;}
}
// constructor
public PeopleBLL()
{
}
// method we are interested in
public IList<Person> GetAllInGroup(int groupID){
//get the group object
Group groupObject = _groupsBLL.Get(groupID);
// get the people in the group
IList<Person> people = _peopleDao.GetAllInGroup(groupObject);
// do something here to sort the people
people.Sort();
// return the list of people to aspx page
return people;
}
}
我以格式
获取列表 person 2
person 1
person 6
person 3
person 5
person 4
但我希望格式为
person 1
person 2
person 4
person 3
person 6
person 5
有什么想法吗?
编辑:
我没有把剩下的内容放进去,因为我不想把所有额外技术的问题混淆,但是因为我被问到了。 Spring.Net用于链接所有对象,我有一个3层架构前端(asp.net页面),业务层和与数据库通信的Dao层。我更新了GetAllInGroup()以显示它所做的一切,但它只是我感兴趣的排序.Dao使用nHibernate Criteria Query来获取组下的所有对象,如下所示。
public IList<Person> getRegistrationsForDonor(Group groupObject) {
IList<Person> rv = CurrentSession.CreateCriteria(typeof(Person),"p")
.CreateCriteria("Groups","g")
.Add(Expression.Eq("g.id", groupObject.id))
.List<Person>();
return rv;
}
所有这些都是在对象数据源
中的aspx页面中启动的 <asp:ObjectDataSource ID="ObjectDataSource1" OnObjectCreating="DataSource_ObjectCreating" runat="server" DataObjectTypeName="Domain.Person" TypeName="BusinessLayer.PersonBLL" DeleteMethod="delete" SelectMethod="GetAllInGroup" UpdateMethod="update">
<SelectParameters>
<asp:ControlParameter ControlID="groupid" Type="Int32" DefaultValue="0" Name="groupID" />
</SelectParameters>
</asp:ObjectDataSource>
然后由gridview使用,所以不幸的是我需要将一个已排序的IList从BLL返回到BLL方法的前端作为单个IList。
修改2
抱歉已经假设所有父母在顶层都是空的,我可以理解这个假设可以来自哪里,但理论上你可以在这个组中只有孩子,所以没有一个对象会有父母的空值。例如,以下是有效的组。
person 2 (2,"Bob",1)
person 4 (4,"Dejgo",2) // child of a child
person 6 (6,"Florence", 3)
我希望会回来
person 2
person 4
person 6
编辑3
不幸的是,所有这些都不能在评论中推测出来,所以我将不得不在这里做出回应。
在17:30尝试了@ jon-senchyna的回答,我肯定越来越近了,我刚刚尝试了一些实时数据并且它几乎就在那里,但我似乎遇到了孩子们在父母面前出现问题在小组中。以第1组中的以下示例为例,有48人,我将重点介绍感兴趣的人。
(789, "person 1", null)
(822, "Person 34", null)
(825, "Person 37", 789)
(3060, "Person 47", 822)
(3061, "Person 48", 825)
这是从数据库返回的顺序,但是当它们按顺序进行排序时
Person 48 - id: 3061
Person 37 - id: 825
Person 1 - id: 789
Person 47 - id: 3060
Person 34 - id: 822
因此,孩子们与父母相邻,但顺序相反,我希望他们按照顺序
Person 1 - id: 789
Person 37 - id: 825
Person 48 - id: 3061
Person 34 - id: 822
Person 47 - id: 3060
答案 0 :(得分:2)
如果你想通过CompareTo这样做,你可能需要更多的comlpex逻辑来处理比较父树。以下是一个可能的解决方案:
public virtual Int32 CompareTo(Person person2)
{
Stack<Person> parents1 = GetParents(this);
Stack<Person> parents2 = GetParents(person2);
foreach (Person parent1 in parents1)
{
Person parent2 = parents2.Pop();
// These two persons have the same parent tree:
// Compare their ids
if (parent1 == null && parent2 == null)
{
return 0;
}
// 'this' person's parent tree is contained in person2's:
// 'this' must be a parent of person2
else if (parent1 == null)
{
return -1;
}
// 'this' person's parent tree contains person2's:
// 'this' must be a child of person2
else if (parent2 == null)
{
return 1;
}
// So far, both parent trees are the same size
// Compare the ids of each parent.
// If they are the same, go down another level.
else
{
int comparison = parent1.id.CompareTo(parent2.id);
if (comparison != 0)
{
return comparison;
}
}
}
// We should never get here anymore, but if we do,
// these are the same Person
return 0;
}
public static Stack<Person> GetParents(Person p)
{
Stack<Person> parents = new Stack<Person>();
// Add a null so that we don't have to check
// if the stack is empty before popping.
parents.Push(null);
Person parent = p;
// Recurse through tree to root
while (parent != null)
{
parents.Push(parent);
parent = parent.Parent;
}
return parents;
}
更新:两个父级堆栈现在都包含原始人员,使比较逻辑更容易。
答案 1 :(得分:0)
只是一个考虑因素:您不需要加载所有人。 如果您只加载没有父级的人,您将检索1,3和5。 您可以使用儿童酒店进入2,4和6。 要获得该顺序中所有6个的列表(没有层次结构),您可以递归地遍历3个根节点并创建最终列表。