【发布时间】:2015-02-27 11:58:10
【问题描述】:
我正在尝试使用 EF 6.1.2 Code First 实现简单的自引用关系。
public class Branch
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public int? ParentId { get; set; }
[ForeignKey("ParentId")]
public virtual Branch Parent { get; set; }
public ICollection<Branch> Children { get; set; } // direct successors
}
在我的应用程序中,我只有一个根分支。并且除了这个单一的根分支之外,每个分支都只有一个父分支(根分支的 parentId 为 NULL)。除此之外,每个分支都可以有 [0..n] 个子分支。
我有两个问题:
- 是否需要在 OnModelCreating(DbModelBuilder modelBuilder) 中指定任何额外的 FluentApi 代码才能让 EF 理解这种一对多的自引用关系?我试过这个:
modelBuilder.Entity<Branch>().HasOptional<Branch>(b => b.Parent).WithMany(b => b.Children).HasForeignKey(b => b.ParentId);但我不确定我是否需要这个。 - 对于给定的分支,我想检索所有子级(一直到层次结构)。到目前为止,这是我想出的:
.
public IEnumerable<Branch> GetBranches(Branch anyBranch)
{
return anyBranch.Flatten(b => b.Children);
}
和
public static IEnumerable<T> Flatten<T>(this T node, Func<T, IEnumerable<T>> selector)
{
return selector(node).SelectMany(x => Flatten(x, selector))
.Concat(new[] { node });
}
第二个 sn-p 不是我写的。我在 StackOverflow 的其他地方找到了它。老实说,我几乎不明白它应该如何工作。
当我运行我的应用程序并调用 GetBranches()(我尝试了几个不同的分支)时,我在 Flatten() 方法中收到了一个异常。错误消息说:“值不能为空。 参数名称:源”。不幸的是,这并没有给我任何线索这里出了什么问题。
我希望有人可以帮助我吗?非常感谢!
【问题讨论】:
标签: entity-framework ef-code-first entity-framework-6