2015-11-09 3 views
1

Возможно ли установить объект по умолчанию для объекта Entity?Установка объекта по умолчанию для свойства навигации Entity Framework

Скажем, у меня есть объект Person, у которого изначально не было требования для Profile.

Теперь мне нужен Profile - но существуют существующие объекты, которые в настоящее время не имеют Profile.

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

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

  • Если Profile является null я хочу, чтобы вернуть значение по умолчанию initialzied объект
  • Если Profileнеnull Я хочу, чтобы вернуть объект из базы данных

Дополнительно - что было бы самый разумный способ привязать объект «default» к моему dbcontext?

Как я могу достичь этого желаемого поведения?

public class Person 
{ 
    [Key] 
    public int Id {get; set;} 

    private Profile _profile; 
    public virtual Profile Profile 
    { 
     get 
     { 
      return _profile ?? (_profile= new Profile 
      { 
       Person = this, 
       PersonId = Id 
      }); 
     } 
     set 
     { 
      _profile = value; 
     } 

     // properties 
    } 
} 

public class Profile 
{ 
    [Key, ForeignKey("Person")] 
    public int PersonId {get; set;} 

    [ForeignKey("PersonId")] 
    public virtual Person Person{ get; set; } 

    // properties 
} 

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

+0

Что вы хотите, чтобы загрузить объект Person, который не имеет профиля в базе данных, а затем обновить некоторое свойство и сохранить его обратно? Должна ли EF создавать профиль для такого человека в базе данных? –

+0

@YacoubMassad Я хочу, чтобы 'Person' без' Profile' имел экземпляр экземпляра 'Profile' - он не должен быть сохранен, если не вызвано' SaveChanges() ', но меня это не так беспокоит часть на данный момент - я просто хочу создать экземпляр 'Profile', если он равен NULL, и если он не равен нулю, загрузите из базы данных как обычно. – Alex

+0

Что это за класс 'User'? Это базовый класс для «Человека»? –

ответ

-1

Да.

Вам просто нужно реализовать свойство IdProfile «get» лично, где должен быть установлен идентификатор профиля.

Позвольте мне показать вам, с помощью текучего API:

public class Person 
{ 
    public int Id {get; set;} 
    private int _idProfile; 
    public int IdProfile { 
     get{ 
      return _idProfile == 0 ? DEFAULT_PROFILE_ID : _idProfile; 
     } 
     set{ 
      _idProfile = value; 
     } 
    } 

    public virtual Profile @Profile; 
} 

public class Profile 
{ 
    public int Id {get; set;} 
    public virtual ICollection<Person> Persons { get; set; } 
} 

/* MAPPING */ 

public class PersonMap : EntityTypeConfiguration<Person> 
{ 
    this.HasRequired(t => t.Profile) 
      .WithMany(t => t.Persons) 
      .HasForeignKey(d => d.IdProfile); 
} 
+0

Извините, я, возможно, не был достаточно ясен. Профиль «default» не используется совместно с несколькими «Person», это просто инициализированный экземпляр «Profile». – Alex

3

Используйте ObjectContext.ObjectMaterialized Event.

Это событие создается для каждого объекта, который загружается в контекст после материализации.

В конструкторе вашего контекста подпишитесь на это событие. И в обработчике события проверьте, является ли тип объекта Person, и если да, создайте новый профиль для этого человека. Вот пример кода:

public class Context : DbContext 
{ 
    private readonly ObjectContext m_ObjectContext; 

    public DbSet<Person> People { get; set; } 
    public DbSet<Profile> Profiles { get; set; } 

    public Context() 
    { 
     var m_ObjectContext = ((IObjectContextAdapter)this).ObjectContext; 

     m_ObjectContext.ObjectMaterialized += context_ObjectMaterialized; 

    } 

    void context_ObjectMaterialized(object sender, System.Data.Entity.Core.Objects.ObjectMaterializedEventArgs e) 
    { 

     var person = e.Entity as Person; 

     if (person == null) 
      return; 

     if (person.Profile == null) 
      person.Profile = new Profile() {Person = person}; 

    } 
} 

Обратите внимание, что если вы вносите изменения, новые профили будут сохранены обратно в базу данных.

+0

Это своего рода аккуратный. Я смог использовать это, чтобы заставить сетку Kendo работать с не сглаженной моделью просмотра, что позволило мне поддерживать производительность (по сравнению с фильтрацией и сортировкой в ​​памяти). В общем, есть ли недостаток в этом? – Charles

Смежные вопросы