如何对自引用表或实体进行排序

时间:2013-12-21 06:35:05

标签: wpf entity-framework sorting

我有两个实体看起来像这样。

public  class Post{
        [Key]
        public int Id { get; set; }

        [Required(ErrorMessage = "")]
        [MaxLength(100, ErrorMessage = "")]
        public string Name { get; set; }

        [ForeignKey("ParentPost")]
        public int? ParentPostId { get; set; }
        public virtual Post ParentPost { get; set; }

        public ICollection<Post> SubPosts { get; set; }
} 

public  class User{
        [Key]
        public int Id { get; set; }

        [Required(ErrorMessage = "")]
        [MaxLength(100, ErrorMessage = "")]
        public string Name { get; set; }

        [ForeignKey("Post")]
        public int PostId { get; set; }
        public virtual Post Post { get; set; }
}

我有一个用户列表,我希望sort Users加上level of Post

例如:

ID---------Name------ParentID
1----------1-----------NULL
2----------1.1----------1
3----------2-----------NULL
4----------1.1.1--------2
5----------1.2----------3 

按级别排序。

1
2
1.1
1.2
1.1.1

1 个答案:

答案 0 :(得分:0)

更新:

这是我之前的答案的替代方案,不需要您在Post中添加属性。为Post实体创建扩展方法,根据Post的名称计算级别和数量。我假设你给它一致的命名。

public static class ExtensionMethods
{
    public static int Level(this Post post)
    {
        var name = post.Name;
        var level = 0;
        level = name.Count(o => o == '.');
        return level;
    }

    public static int number(this Post post)
    {
        var name = post.Name;
        var number = 0;
        var split = name.Split('.');
        return split.Length > 1 ? int.Parse(split[split.Length - 1]) : int.Parse(name);
    }
}

然后你可以使用linq排序:

var posts = new List<Post>();
posts.Add(new Post { Name = "1.2" });
posts.Add(new Post { Name = "1.1.1" });
posts.Add(new Post { Name = "2" });
posts.Add(new Post { Name = "1.1" });
posts.Add(new Post { Name = "1" });
foreach (var post in posts)
{
    Console.WriteLine(post.Name);
}
Console.WriteLine("\n\nAfter sorting");
var sorted = posts.OrderBy(p => p.Level()).ThenBy(p => p.number());
foreach (var post in sorted)
{
    Console.WriteLine(post.Name);
}

以前的答案:

我无法想到Post实体的当前属性的正确解决方案。我想到了一些逻辑,但那些并不完美,会在某些条件下破裂。

我能想到的正确解决方案是在Post中添加两个属性。用于存储Post级别的Level属性,以及用于存储Name中最后一个点之后的数字的Number属性(1用于帖子名称1.1.1,10用于帖子名称2.1.10等)。使用这两个附加属性,您可以对Post进行排序,如下所示:

Posts.OrderBy(p => p.Level)
    .ThenBy(p => p.Number);