Entity Framework - Загрузка сущностей с дочерней сущностью - PullRequest
3 голосов
/ 27 сентября 2011

Я пытаюсь загрузить все сущности A в базу данных вместе с сущностями B. Отношения между ними: «Каждый А имеет право», имеет одно право «Б».

В проекте, над которым я работаю, есть шаблон репозитория и метод All (), как показано ниже.

    public class EFRepository<T> : IRepository<T> where T : class, IObjectWithChangeTracker
        {
private IObjectSet<T> objectset;

        private IObjectSet<T> ObjectSet
        {
            get
            {
                if (objectset == null)
                {
                    objectset = UnitOfWork.Context.GetObjectSet<T>();
                }
                return objectset;
            }
        }
    public virtual IQueryable<T> All()
            {
                return ObjectSet.AsQueryable();
            }
    }

Есть ли способ, которым я могу заставить объекты B активно загружаться. Я обнаружил, что в IQueryable нет метода Include, который возвращается из метода All (). Я счастлив добавить нового члена в repositroy, чтобы он мог позволить клиенту использовать нетерпеливую загрузку. Но как я могу это сделать?

Ответы [ 2 ]

4 голосов
/ 27 сентября 2011

Проблема в том, что IQueryable не зависит от того, что его поддерживает, а Include - это функция Entity Framework.У вас может быть IQueryable, который вместо этого использует LINQ to Objects, и Include не будет иметь смысла там.Проще всего было бы изменить тип All() на IObjectSet, из которого вы должны иметь доступ к Include методу расширения.

Если вы не можете изменить тип возвращаемого значения All, вам придется структурировать свои запросы таким образом, чтобы они охотно включали дочерние элементы.

IList<Parent> parentsWithEagerLoadedChildren = parentRepo.All()
    .Select(p => new {p, p.Children}).ToList() // EF will attach the children to each parent
    .Select(p => p.p).ToList(); // Now that everything is loaded, select just the parents
1 голос
/ 27 сентября 2011

Вы можете создать свой собственный метод расширения, который позволит вам использовать Include(path) против любого IQueryable<T>:

public static IQueryable<TSource> Include<TSource>
  (this IQueryable<TSource> source, string path)
{
  var objectQuery = source as ObjectQuery<TSource>;
  if (objectQuery != null)
  {
    return objectQuery.Include(path);
  }
  return source;
}

В блоге Джули Лерман есть полное объяснение: http://thedatafarm.com/blog/data-access/agile-entity-framework-4-repository-part-5-iobjectset/

...