带有Dapper的分层树表

时间:2018-08-11 18:49:59

标签: c# orm dapper

我有一个任务要用Dapper制作一个嵌套的树形视图。但是我不确定是否做对了。也许有一种更有效,更漂亮的方式,只需更少的代码。我可以在.Query()之后加上一些点而没有FillRecursively()函数来获得相同的结果吗? (QueryMultiple,Multimapping等)。

示例如下:

public class TestPersonViewModel
{
    public IEnumerable<Person> PersonList { get; set; }

    public class Person
    {
        public int Id { get; set; }
        public IEnumerable<Person> Children { get; set; }
        public string Name { get; set; }
    }

    public class PersonInDb
    {
        public int Id { get; set; }
        public int? ParentId { get; set; }
        public string Name { get; set; }
    }

    public void GetNestedSet(IProductRepository repo, int? personId)
    {
        var queryParams = new { Id = (int?)personId };

        string queryText = @"
            WITH RECURSIVE r AS (
                SELECT p.id, p.name, p.parent_id FROM persons as p           
                WHERE CASE WHEN @Id IS NULL THEN TRUE ELSE p.id = @Id END

                UNION

                SELECT persons.id, persons.name, persons.parent_id FROM r
                JOIN persons ON persons.parent_id = r.id
            )
            SELECT r.id, r.name, r.parent_id as parentid, p.name as parent FROM r LEFT JOIN persons as p
            ON r.parent_id = p.id
        ";

        List<PersonInDb> sourceTable = repo.Context.Database.GetDbConnection()
            .Query<PersonInDb>(queryText, queryParams).ToList();


        HashSet<Person> personList;
        FillRecursively(ref sourceTable, out personList, personId);
        PersonList = personList as IEnumerable<Person>;

    }

    private void FillRecursively(ref List<PersonInDb> sourceTable, out HashSet<Person> outValue,  int? currentId)
    {
        var matches = sourceTable.Where(r => r.ParentId == currentId).ToArray();
        sourceTable.RemoveAll(r => r.ParentId == currentId);
        outValue = new HashSet<Person>();

        foreach (var row in matches)
        {
            var newPerson = new Person {
                Name = row.Name,
                Id = row.Id
            };

            var newChildren = new HashSet<Person>();
            FillRecursively(ref sourceTable, out newChildren, newPerson.Id);
            newPerson.Children = newChildren;

            outValue.Add(newPerson);
        }
    }
}

0 个答案:

没有答案