EF4 - Простой способ загрузить все связанные объекты? - PullRequest
2 голосов
/ 03 декабря 2011

В EF4 есть относительно простой способ загружать все связанные сущности сущности? Я думаю, что метод расширения был бы идеальным для этого. У меня есть сценарий, в котором я использую POCO, и один из объектов имеет несколько навигационных свойств других объектов, а те, в свою очередь, имеют свои собственные свойства навигации. Само собой разумеется, что много циклов и загрузок, чтобы нетерпеливо загрузить все. Я хочу, чтобы все свойства были загружены и готовы при вызове метода расширения, чтобы я мог отключить LazyLoading.

Что-то вроде:

using(var context = new MyEntities())
{
   var widget = context.Widgets.FirstOrDefault();
   widget.RecursivelyLoadAllPropertiesForMe() // magical extension method I wished existed
}

Ответы [ 4 ]

2 голосов
/ 05 декабря 2011

Вот метод расширения, который я придумал:

public static void LoadAllProperties<T>(this T entity, ObjectContext context)
{
    Type type = entity.GetType();
    context.Refresh(RefreshMode.ClientWins, entity);
    foreach (var property in type.GetProperties())
    {
        if (property.PropertyType.Name.StartsWith("ICollection"))
        {
            context.LoadProperty(entity, property.Name);
            var itemCollection = property.GetValue(entity, null) as IEnumerable;
            foreach (object item in itemCollection)
            {
                item.LoadAllProperties(context);
            }
        }
    }
}

Этот метод сначала загружает значения свойств нормального объекта, обновляя объект из контекста.Затем он просматривает каждое свойство в поисках свойств навигации, которые являются коллекциями, и будет рекурсивно загружать каждый элемент в коллекции.Это работает довольно хорошо для того, что мне было нужно, и не требует от вас использования прокси или включений.

Использование:

using(var context = new MyEntities())
{
    context.ContextOptions.ProxyCreationEnabled = false;
    var widget = context.Widgets.FirstOrDefault();  
    widget.LoadAllProperties(context);
}
2 голосов
/ 04 декабря 2011

Стремительная загрузка всегда явная - без автоматизации. Вы должны определить, включает в себя все отношения, которые вы хотите загрузить. Если вы этого не сделаете, вы почти всегда закончите с решением, используя новый запрос для каждого отношения.

Ваш метод расширения должен использовать:

((EntityCollection<...>)entity.NavigationCollection).Load();

Если вам нужно загрузить подчиненные отношения, вы также можете позвонить:

((EntityCollection<...>)entity.NavigationCollection).CreateSourceQuery()
                                                    .Include(...)
                                                    .Execute();

Но каждый вызов Load или Execute все равно будет создавать новый запрос к базе данных, и вы должны написать код, который будет выполнять эти вызовы. Кроме того, у вас должны быть прокси-объекты, чтобы иметь возможность преобразовывать общие ICollection<...> в EntityCollection<...>, и вы должны загружать все простые навигационные свойства (не коллекции) с общей энергичной загрузкой.

0 голосов
/ 16 августа 2012

шаг 1
context.DataContext.ContextOptions.ProxyCreationEnabled = true; context.DataContext.ContextOptions.LazyLoadingEnabled = true;

шаг 2 добавить виртуальное ключевое слово в свойство навигатора

  public class BankBranche 
   {
    public int Id { get; set; }

    public string Name { get; set; }

    public string Code { get; set; }

    public int BankId { get; set; }

    public virtual Address Address { get; set; }

    public virtual Bank Bank { get; set; }

}

0 голосов
/ 16 августа 2012

Да, есть! Просто иди:

widget.Load()

Или, если вы пошли:

var widget = context.Widgets.FirstOrDefault().Include("SomeRelatedEntities").Include("OtherRelatedEntities");

тебе не нужно!

...