1

I have tried to Eagerly load all the data related to an entity, but I still have a problem regarding the recusive properties like this one :

  public class Node : BaseAbstractEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }


    [ForeignKey("TypeId")]
    public virtual NodeType Type { get; set; }
    public int? TypeId { get; set; }


    [ForeignKey("ParentId")]
    public virtual Node Parent { get; set; }
    public int? ParentId { get; set; }


    public ICollection<Node> Children { get; set; }
}

I am using it in this method :

 public async Task<object> JustGetAsync(Type type, JObject value, DbContext context)
    {
        int id = 0;
        if (value != null && value["id"] != null)
            id = Int32.Parse(value["id"].ToString());

        if (id != 0)
            return await context.FindAsync(type, id);

        var TypeSet = (IQueryable<object>) context.GetType()
                                                  .GetMethod("Set")
                                                  .MakeGenericMethod(type)
                                                  .Invoke(context, null);

        return await TypeSet.Include(context.GetIncludePaths(type)).ToListAsync();
    }

the get IncludePaths is a code that I found here enter link description here that helps to eager all the properties :

public static IQueryable Include(this IQueryable source, IEnumerable navigationPropertyPaths) where T : class { return navigationPropertyPaths.Aggregate(source, (query, path) => query.Include(path)); }

    public static IEnumerable<string> GetIncludePaths(this DbContext context, Type clrEntityType)
    {
        var entityType = context.Model.FindEntityType(clrEntityType);
        var includedNavigations = new HashSet<INavigation>();
        var stack = new Stack<IEnumerator<INavigation>>();
        while (true)
        {
            var entityNavigations = new List<INavigation>();
            foreach (var navigation in entityType.GetNavigations())
            {
                if (includedNavigations.Add(navigation))
                    entityNavigations.Add(navigation);
            }
            if (entityNavigations.Count == 0)
            {
                if (stack.Count > 0)
                    yield return string.Join(".", stack.Reverse().Select(e => e.Current.Name));
            }
            else
            {
                foreach (var navigation in entityNavigations)
                {
                    var inverseNavigation = navigation.FindInverse();
                    if (inverseNavigation != null)
                        includedNavigations.Add(inverseNavigation);
                }
                stack.Push(entityNavigations.GetEnumerator());
            }
            while (stack.Count > 0 && !stack.Peek().MoveNext())
                stack.Pop();
            if (stack.Count == 0) break;
            entityType = stack.Peek().Current.GetTargetType();
        }
    }
  • Hello! Does this answer your question?https://stackoverflow.com/questions/40987365/implementing-recursive-property-loading-in-ef-core –  Dec 18 '19 at 12:56
  • Not in my case, In fact I am willing to get any type given, it's kinda generic, so I cannot simlply make it for the specific Node entity case – developper8036 Dec 18 '19 at 14:28
  • Even if you get this to work, this is such a hugely bad idea it's not even funny. Just eagerly loading all relationships recursively without any thought could destroy your database, depending on how many related entities there are and how deep the rabbit hole goes. You could potentially end up loading in half your database in a single query. Queries should be intentionally deliberate, which is why EF doesn't give you a built in a way to do something crazy like this. – Chris Pratt Dec 18 '19 at 14:30
  • @ChrisPratt I understand that point of view, but this feature is made for a specific reason, and other layers of control will be implemented just not to allow that case from happening, the problem is that this feature exists on other ORMs, but here on EF it doesn't. – developper8036 Dec 18 '19 at 14:40
  • *On purpose.* This is an anti-pattern, and EF doesn't handle it as a result. Not sure what ORM you've used that does allow this. It's one thing if it's a known type, because then you're still making a conscious choice that it's fine to load all the relationships, but allowing this for just any old entity is a recipe for disaster. – Chris Pratt Dec 18 '19 at 14:43

0 Answers0