2

エンティティフレームワークで自己参照テーブルを正常に使用しています。しかし、私は希望の深さの記録を取得する方法を理解できませんか?

このためのロジックはどうあるべきですか?


モデル :

public class FamilyLabel
{
    public FamilyLabel()
    {
        this.Children = new Collection<FamilyLabel>();
        this.Families = new Collection<Family>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int FamilyLabelId { get; set; }
    public string FamilyLabelName { get; set; }

    public virtual FamilyLabel Parent { get; set; }

    public int JamaatId { get; set; }
    public virtual Jamaat Jamaat { get; set; }

    public virtual ICollection<Family> Families { get; set; }
    public virtual ICollection<FamilyLabel>  Children { get; set; }
}
4

1 に答える 1

4

理論的には、指定された深度レベルに基づいてクエリ式を動的に構築するメソッドを作成できます。

context.FamilyLabels.Where(x => 
    x.Parent. ... .Parent != null &&
    x.Parent.Parent ... .Parent == null);

次の実装はトリックを行います:

public static IList<FamilyLabel> Get(DbConnection connection, int depth)
{
    var p = Expression.Parameter(typeof(FamilyLabel));
    Expression current = p;

    for (int i = 0; i < deep; i++)
    {
        current = Expression.Property(current, "Parent");
    }

    var nullConst = Expression.Constant(null, typeof(FamilyLabel));

    var predicate = Expression.Lambda<Func<FamilyLabel, bool>>(
        Expression.AndAlso(
            Expression.NotEqual(current, nullConst),
            Expression.Equal(Expression.Property(current, "Parent"), nullConst)), p);

    using (MyDbContext context = new MyDbContext(connection))
    {
        return context.FamilyLabels.Where(predicate).ToList();
    }
}

ただし、おそらくこれにより多数の結合式が作成されるため、これが最適な方法ではない可能性があります。

于 2013-03-26T11:57:43.897 に答える