オブジェクトのすべてのレベルをEFに含めるにはどうすればよいですか?[複製]

Nov 23 2020

ネットワーク構造を定義するオブジェクトがあり、そのオブジェクトのすべての子と子の子などを送信したいと思います。

今私はこれを持っています:

var Data = await _context.Scans
                .Include(c => c.networkDevices)
                .ThenInclude(d => d.ports)
                .ThenInclude(p => p.Service)
                .Include(c => c.root)
                .ThenInclude(d => d.children).ThenInclude(p => p.children).ThenInclude(c => c.children)
                .ToListAsync();
            return Data;

このコードはほとんどのレベルを取得しますが、ネットワークに多くの異なるレイヤーがある場合、すべてを取得することはできません。すべてのレイヤーが含まれるようにするにはどうすればよいですか。

回答

1 Dominik Nov 23 2020 at 20:21

理論的には循環参照がある可能性があるため、「すべての」レイヤーをロードする組み込みの方法はないと思います。

このスニペットは、レイヤー数のクエリを作成します

namespace System.Data.Entity
{
  using Linq;
  using Linq.Expressions;
  using Text;

  public static class QueryableExtensions
  {
    public static IQueryable<TEntity> Include<TEntity>(this IQueryable<TEntity> source,
      int levelIndex, Expression<Func<TEntity, TEntity>> expression)
    {
      if (levelIndex < 0)
        throw new ArgumentOutOfRangeException(nameof(levelIndex));
      var member = (MemberExpression)expression.Body;
      var property = member.Member.Name;
      var sb = new StringBuilder();
      for (int i = 0; i < levelIndex; i++)
      {
        if (i > 0)
          sb.Append(Type.Delimiter);
        sb.Append(property);
      }
      return source.Include(sb.ToString());
    }
  }
}

使用法:

var children = await DbContext.Roots
  .Include(3, a => a.Children)
  .SingleOrDefaultAsync(a => a.Id == 5);
rodrigo.cantunes Nov 23 2020 at 20:40

これを実現する最も簡単な方法は、遅延読み込みを使用することだと思います。この投稿をご覧ください