1

我有一个数据库表,它代表具有多级层次结构的帐户。每行都有一个代表当前帐户的“AccountKey”,可能还有一个代表父级“AccountKey”的“ParentKey”。

我的模型类是“AccountInfo”,其中包含有关帐户本身的一些信息,以及子帐户列表。

将这种平面数据库结构转换为层次结构的最简单方法是什么?它可以直接在 LINQ 中完成,还是我需要在事后循环并手动构建它?

模型

public class AccountInfo
{
    public int AccountKey { get; set; }
    public int? ParentKey { get; set; }
    public string AccountName { get; set; }

    public List<AccountInfo> Children { get; set; } 
}

LINQ

var accounts =
    from a in context.Accounts
    select new AccountInfo
        {
            AccountKey = a.AccountKey,
            AccountName = a.AccountName,
            ParentKey = a.ParentKey                            
        };
4

2 回答 2

1

您当前拥有的结构实际上是一个层次结构(邻接列表模型)。问题是,你想保留这个分层模型吗?如果你这样做,有一个名为 MVCTreeView 的 Nuget 包。这个包直接与您描述的表结构一起工作 - 在其中,您可以为您的 UI 创建一个树视图,在每个级别实现 CRUD 操作等。我必须这样做,我在 CodeProject 上写了一篇文章,展示了如何通过 C# 级联删除 SQL 中的邻接列表模型表。如果您需要更多细节,请发表评论,我会编辑这篇文章。

http://www.codeproject.com/Tips/668199/How-to-Cascade-Delete-an-Adjace

于 2013-10-14T19:54:36.577 回答
1

您可以简单地为父键创建关联属性:

public class AccountInfo {
    ... // stuff you already have
    public virtual AccountInfo Parent { get; set; }
}

// in the configuration (this is using Code-first configuration)
conf.HasOptional(a => a.Parent).WithMany(p => p.Children).HasForeignKey(a => a.ParentKey);

使用此设置,您可以通过延迟加载在查询中或查询外部沿任一方向遍历层次结构,如果您想要延迟加载子项,请确保将属性设为虚拟。

要选择给定父级的所有子级,您可以运行以下查询:

var children = context.Accounts
    .Where(a => a.AccountKey = someKey)
    .SelectMany(a => a.Children)
    .ToArray();
于 2013-10-14T19:49:27.773 回答