Reputation: 6977
I am successfully using a self referencing table in entity framework. But I can't figure out how to get the records of the desired depth ?
What should be the logic for this ?
Model :
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; }
}
Upvotes: 2
Views: 1502
Reputation: 1078
Theoretically you can create a method that builds query expression dynamically based on the specified depth level:
context.FamilyLabels.Where(x =>
x.Parent. ... .Parent != null &&
x.Parent.Parent ... .Parent == null);
The following implementation does the trick:
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();
}
}
However, presumably this will create a bunch of join expressions, so maybe this is not the most optimal way.
Upvotes: 4