2016-12-15 46 views
1

我正在使用EF核心1.1在一個asp.net mvc核心項目上,偶然發現,我認爲是非最優的SQL生成。但是,嘿,我不是專家,所以我可能是錯完全地:)實體框架核心模型一對一

模式

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

    public Instagram Instagram { get; set; } 

    public YouTube YouTube { get; set; } 

    // In the future, more social channels will be added so 
    // this is another concern I have how to architect/model properly 
} 

public class Instagram 
{ 
    public int Id { get; set;} 
    public string UserId { get; set; } 
    // More properties such as bio, image url, website and other stuff 
} 

public class YouTube 
{ 
    public int Id { get; set; } 
    public string ChannelId { get; set; } 
    // More properties such as bio, image url, statistics etc 
} 

UserIdChannelId是「自然鍵」(原諒我正確的SQL術語濫用:)和Id屬性「artifical keys」,希望創建一個接口/基類來簡單地執行各種操作,例如刪除,刷新。

所以對於這個問題 - 如何正確設置這個在modelBuilder是正確的?

我覺得應該是最好的SQL是一樣的東西

Instagram 
- Id (PK) 
- UserId (AK) 
- InfluencerId (FK) 
YouTube 
- Id (PK) 
- ChannelId (AK) 
- InfluencerId (FK) 
Influencer 
- Id 

這應該有效約束的影響者和其關聯的社交平臺,以及約束之間的一個一對一的關係,沒有影響者的份額同樣的社交平臺(只是寫它使我不確定我是否真的想要這樣做,因爲可能會出現這樣的情況,例如一對夫婦共享相同的youtube頻道,但是是兩個獨立的影響者)。考慮到上述設計,比推出它更容易實現稍後)

關於目前的造型

modelBuilder 
    .Entity<InstagramChannel>() 
    .HasAlternateKey(i => i.UserId) 
    .HasName("AK_UserId"); 

modelBuilder 
    .Entity<Profile>() 
    .HasOne<Instagram>() 
    .WithOne() 
    .HasForeignKey(typeof(Instagram), "ProfileId") 
    .HasConstraintName("FK_Instagram_Profile") 
    .OnDelete(DeleteBehavior.Cascade); 

然而這產生一個鍵,每一個社交平臺的InfluencerInfluencer.InstagramIdInfluencer.YouTubeId造成兩處更改數據庫時,一個社交平臺被刪除。

編輯 因此,標記爲未映射的屬性Instagram, YouTube生成了我正在查找的SQL。但現在我不確定我是否遺漏了某些東西 - 如果「父表」與其相關表有直接關係,那麼EF核可能會啓用某些優化。也許這只是使EF無法評估Include(i => i.Instagram)聲明,因爲它可能想要這樣做而不需要需要加入。

這麼長的帖子,也許不是一個真正的問題(好吧,我說了:)而且可能不適合在這個論壇上。但是,嘿,有很多偉大的男人和女孩可能不想分享他們的知識!

感謝

回答

1

你可以達到你的目的,即使沒有使用modelBuilder,使用屬性:

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

    [InverseProperty("Influencer")] 
    public Instagram Instagram { get; set; } 

    [InverseProperty("Influencer")] 
    public YouTube YouTube { get; set; } 
} 

public class Instagram 
{ 
    public int Id { get; set;} 
    public string UserId { get; set; } 

    public int InfluencerId { get; set; } 

    [ForeignKey("InfluencerId")] 
    public virtual Influencer Influencer { get; set; } 
} 

public class YouTube 
{ 
    public int Id { get; set; } 
    public string ChannelId { get; set; } 

    public int InfluencerId { get; set; } 

    [ForeignKey("InfluencerId")] 
    public virtual Influencer Influencer { get; set; } 
} 

您可以刪除InfluencerId屬性,如果你不喜歡他們(我喜歡有明確的ID字段能夠在那裏設置int值而不是分配Influencer實例並僅從DB讀取它們)。

此外,您可能會刪除virtual關鍵字,因爲EF核心(目前)並不需要他們(但它也不支持惰性加載,所以我比較喜歡的情況下,保持「虛擬」將更新版本)

+0

謝謝!將嘗試這一點,它看起來乾淨 - 然後模型生成器語法更詳細。是否可以使用數據註釋添加唯一約束? – joacar

+0

不,目前EF Core不支持'Index'屬性(但在github上有一個[issue](https://github.com/aspnet/EntityFramework/issues/4050)關於添加它) – Dmitry