Расщепление таблиц Entity Framework - как инициализировать лениво загруженные свойства?

Используя Entity Framework 6.0, я пытаюсь реализовать разбиение таблиц для повышения производительности запросов к таблицам со столбцами, содержащими данные BLOB. Я следовал рекомендациям этого урока, и он действительно работает, как описано.

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

public class MyEntity
{
    public string Id { get; set; }      

    public virtual MyEntityContent Content { get; set; }

    public string Name { get; set; }
}

public class MyEntityContent
{
    public string Id { get; set; }      

    public virtual MyEntity Entity { get; set; }

    public byte[] Blob { get; set; }
}

... и соответствующий код конфигурации в соответствующем DbContext реализация...

modelBuilder.Entity<MyEntity>().HasKey(e => e.Id).ToTable("MyEntities");
modelBuilder.Entity<MyEntityContent>().HasKey(c => c.Id).ToTable("MyEntities");
modelBuilder.Entity<MyEntity>().HasRequired(e => e.Content).WithRequiredPrincipal(d => d.Entity);

Учитывая, что ленивый груз Content свойство Required Entity Framework кажется разумным инициализировать его значением по умолчанию в конструкторе содержащего MyEntity учебный класс...

public MyEntity()
{
    Content = new MyEntityContent();                
}

... который позволяет создать и частично заполнить новый экземпляр класса без риска возникновения исключения, забыв инициализировать требуемое значение свойства:

var entity = new MyEntity {Id = "XXX", Name = "something"};

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

Это кажется мне нелогичным. Разве Entity Framework не создает объект-сущность, сначала вызывая его конструктор по умолчанию, а затем применяя собственные значения свойств к созданному экземпляру? Если это так, это должно переписать мой по умолчанию Content значение свойства с новым экземпляром MyEntityContentна основе данных базы данных. Вот как это работает с лениво загруженными свойствами коллекции.

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

1 ответ

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

У меня только что была эта проблема с сущностью с двумя виртуальными полями. Первоначально у меня было это инициализировать эти два, но после удаления их (и инициализации других полей к некоторому значению по умолчанию), это начало работать для меня. Попробуйте и дайте мне знать!

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

Другие вопросы по тегам