2015-11-09 94 views
1

是否可以爲實體設置默認對象?爲實體框架導航屬性設置默認對象

說我有一個Person實體,最初沒有要求Profile

現在我需要一個Profile - 但有一些現有的實體目前沒有Profile

有沒有一種方法,我可以提供,當他們在未來會加載這些實體默認的對象,因此,使用Person實體任何人都可以假定Profile永遠不能爲null,總是有一個值 - 即使它是一個默認值。

下面你可以看到我已經嘗試過 - 哪些會創建一個默認值 - 但即使數據庫中有某些東西,它總是會返回默認對象。

  • 如果Profilenull我想回到默認initialzied對象
  • 如果Profilenull我想從數據庫中

此外返回對象 - 這將是將「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 
} 

我知道你可以初始化集合,使它們不爲null,但我也想初始化一個對象。

+0

當你在數據庫中加載沒有配置文件的'Person'對象時,你想要發生什麼,然後更新它的一些屬性並保存回去? EF應該爲數據庫中的這個人創建一個配置文件嗎? –

+0

@YacoubMassad我希望沒有'Profile'的'Person'擁有'Profile'的實例化實例 - 除非調用SaveChanges()',否則不必保存 - 但我並不擔心這個問題部分 - 我只是想實例化一個'Profile',如果它是空的,如果它不爲空,就像正常情況下從數據庫加載。 – Alex

+0

這是什麼'User'類?它是'Person'的基類嗎? –

回答

-1

是的。

您只需要實施IdProfile'get'屬性,其中必須設置配置文件ID。

讓我試着告訴你用流利的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

對不起,我可能不夠清楚。 「默認」配置文件不是通過多個「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 Grid運行在非扁平視圖模型上,這使我能夠保持性能(與內存中的過濾和排序相比)。一般來說,這樣做有什麼缺點嗎? – Charles