Entity Framework с отключенным созданием прокси и отложенной загрузкой по-прежнему загружает дочерние объекты

У меня есть некоторые проблемы с Entity Framework, использующей POCO, и я надеюсь, что кто-то может сказать мне на высоком уровне, ожидается ли поведение, которое я вижу, или мне нужно глубже понять, почему это происходит.

У меня есть класс Customer и еще один CustomerType, поэтому Customer имеет свойство Type (типа CustomerType, указывающее тип), а CustomerType имеет свойство Customers, которое представляет собой набор Customer (все Customer, которые имеют этот тип). Таким образом, это в основном свойства навигации на оба конца ассоциации, в результате чего код POCO выглядит примерно так:

public partial class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int TypeId { get; set; }
    public CustomerType Type { get; set; }
}

public partial class CustomerType
{
    public CustomerType()
    {
        this.Customers = new HashSet<CustomerType>();
    }

    public int Id { get; set; }
    public string TypeName { get; set; }

    public virtual ICollection<Customer> Customers { get; set; }
}

Я отключил создание прокси и отложенную загрузку (т. е. как DbContext.Configuration.ProxyCreationEnabled=false, так и DbContext.Configuration.LazyLoadingEnabled=false), потому что они затрудняют сериализацию.

Как и ожидалось, когда я получаю экземпляры из набора Customer, свойство Type для них по умолчанию равно null.

Но если я получаю экземпляры из набора Customer с .Include("Type"), он не только загружает свойства Type, но также загружает дочерние элементы, то есть набор Customer для каждого из них.

Ожидается ли это?


person mutex    schedule 14.05.2013    source источник
comment
Я понятия не имею, что вы имеете в виду под MyClass и MyClassType. Возможно, вы могли бы написать свой код C# для двух классов вместо того, чтобы пытаться его описать.   -  person Aron    schedule 14.05.2013
comment
Извините, название было запутанным - мои правки делают его более понятным? Это просто примеры, чтобы попытаться проиллюстрировать концепцию.   -  person mutex    schedule 14.05.2013
comment
Нет... Не помогает. Посмотрите здесь пример того, как вы должны описать свой классы. Мы здесь разработчики, а не англоязычные специалисты. Мы считаем, что код легче читать, чем прозу.   -  person Aron    schedule 14.05.2013
comment
Это полу ожидаемо. Расширение Include влияет на выполняемый SQL. Те CustomerType, которые загружены (в силу включения в запрос Customer), будут встроены в дерево объектов в соответствии со столбцом CustomerType.ParentId. Поэтому, если по какой-то случайности и родитель, и дочерний элемент загружаются в один и тот же запрос, дочерний элемент будет помещен в родительский.   -  person Aron    schedule 14.05.2013
comment
Комментарий @ Арона кажется ответом - сделайте репост как ответ, чтобы его можно было принять?   -  person Chris Moschini    schedule 14.05.2013


Ответы (1)


Это полу ожидаемо. Расширение Include влияет на выполняемый SQL. Те CustomerType, которые загружены (благодаря включению в запрос Customer), будут встроены в дерево объектов в соответствии со столбцом CustomerType.ParentId.

Поэтому, если по какой-то случайности и родитель, и дочерний элемент загружаются в один и тот же запрос, дочерний элемент будет помещен в родительский.

person Aron    schedule 14.05.2013
comment
Спасибо, да, я подтвердил тестовый проект. Это очень раздражает для сериализации, но я думаю, что решение состоит в том, чтобы удалить автоматически созданное свойство Customers в CustomerType. PS: у меня была небольшая ошибка в моих определениях классов, поэтому ваш ответ, вероятно, должен быть следующим: Те клиенты, которые загружены, будут встроены в дерево объектов в соответствии со столбцом Customer.TypeId - person mutex; 15.05.2013