我有一个任务要用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);
}
}
}