2013-04-01 34 views
4

我正在建模音樂曲目和專輯,其中專輯有很多曲目,曲目只能放在一張專輯上,連接表指定它在專輯列表中的位置。EF5 Code First Fluent EntityTypeConfiguration用於曲目和專輯模型

這裏是我的模型:

public class Track 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public int AlbumTrackId { get; set; } 
    public virtual AlbumTrack AlbumTrack { get; set; } 
} 

public class Album 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<AlbumTrack> AlbumTracks { get; set; } 
} 

public class AlbumTrack 
{ 
    public int AlbumId { get; set; } 
    public virtual Album Album { get; set; } 

    public int TrackId { get; set; } 
    public virtual Track Track { get; set; } 

    public int Position { get; set; } 
} 

和我EntityTypeConfiguration

public class AlbumTrackConfiguration : EntityTypeConfiguration<AlbumTrack> 
{ 

    public AlbumTrackConfiguration() 
    { 
     // AlbumTrack has a composite key 
     HasKey(at => new {at.AlbumId, at.TrackId}); 

     // AlbumTrack has one Album, Albums have many AlbumTracks 
     HasRequired(at => at.Album) 
      .WithMany(a => a.AlbumTracks) 
      .HasForeignKey(at => at.AlbumId) 
      .WillCascadeOnDelete(true); 

     // AlbumTrack has one Track, Tracks have one AlbumTrack 
     HasRequired(at => at.Track) 
      .WithRequiredPrincipal(t=>t.AlbumTrack) 
      .WillCascadeOnDelete(true); 
    } 

} 

的一個相冊之間一對多的關係AlbumTracks是好的,但除了預期

[AlbumTrackId] [int] NOT NULL, 

Code First不斷添加

[AlbumTrack_AlbumId] [int] NOT NULL, 
[AlbumTrack_TrackId] [int] NOT NULL 

到曲目表。

如何更好地建立跟蹤到專輯跟蹤的關係,以便只有指定的屬性可以在數據庫字段中轉換?

[是,在我的世界的軌道,只能存在於一個單一的專輯!]

感謝。

回答

5

使得Track的位置部分有意義的建議。
但是,如果你還是會希望你的「加入」表來工作 - 我個人總是而是來自他們的「關聯」,即位置等等

對於工作,你撇清軌道,相冊需要重新組織你的人際關係。 EF/CF無法構建 - 因爲您要求的是某些本質上不支持或預期的內容。加入,索引表總是期待在另一方面'多樣性'。

基本上,你的AlbumTrack不再是「加入」表 - 但僅僅是一個 與one-on-oneTrack +你必須從 AlbumTrack的Album FK。

考慮到這一點,你可以做以下 - 這會創造列,索引恰到好處......

public class Track 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    // public int AlbumTrackId { get; set; } 
    public virtual AlbumTrack AlbumTrack { get; set; } 
} 
public class AlbumTrack 
{ 
    public int TrackId { get; set; } // <== this is a single primary 
    public virtual Track Track { get; set; } 

    public int AlbumId { get; set; } 
    public virtual Album Album { get; set; } 

    public int Position { get; set; } 
} 
public class Album 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<AlbumTrack> AlbumTracks { get; set; } 
} 

...並用流利的配置:

modelBuilder.Entity<AlbumTrack>() 
    .HasKey(at => new { at.TrackId }); 
    //.HasKey(at => new { at.AlbumId, at.TrackId }); 

modelBuilder.Entity<AlbumTrack>() 
      .HasRequired(at => at.Track) 
      .WithOptional(a => a.AlbumTrack); 
      // .WithRequiredPrincipal(x => x.AlbumTrack); 

modelBuilder.Entity<AlbumTrack>() 
    .HasRequired(at => at.Album) 
    .WithMany(a => a.AlbumTracks) 
    .HasForeignKey(at => at.AlbumId) 
    .WillCascadeOnDelete(true); 

...你可以用它喜歡:

var album1 = db.Albums.Add(new Album { Name = "Track1", }); 

var tr1 = db.Tracks.Add(new Track { Name = "Track1", }); 
var tr2 = db.Tracks.Add(new Track { Name = "Track2", }); 
var tr3 = db.Tracks.Add(new Track { Name = "Track3", }); 
var tr4 = db.Tracks.Add(new Track { Name = "Track4", }); 
var tr5 = db.Tracks.Add(new Track { Name = "Track5", }); 

db.AlbumTracks.Add(new AlbumTrack { Track = tr1, Album = album1, Position = 1 }); 
db.AlbumTracks.Add(new AlbumTrack { Track = tr2, Album = album1, Position = 2 }); 
db.AlbumTracks.Add(new AlbumTrack { Track = tr3, Album = album1, Position = 3 }); 
db.AlbumTracks.Add(new AlbumTrack { Track = tr4, Album = album1, Position = 4 }); 
db.AlbumTracks.Add(new AlbumTrack { Track = tr5, Album = album1, Position = 5 }); 

db.SaveChanges(); 

(或你的CA ñ只是'添加'專輯曲目,其餘的將進入)。

注:你並不需要組合鍵任何更多 - 因爲你AlbumTrack基本上依賴單獨的軌道上 - 即你有only one record每個軌道 - 與「專輯」附加到。
另外你也不需要// public int AlbumTrackId { get; set; },因爲那是相反的一面,fk在專輯曲目中。而且這在舊的設置中也是錯誤的(因爲你需要'兩鍵'來加入表格)。

而且,添加,這整個結構「意味着」基本上你是簡單的「分裂」的跟蹤表 - 爲兩個一到一個表 - 而你也可以去剛剛曲目/專輯。但是它有它自己的優點 - 當你有額外的連接和讀/寫(不利的方面)時,你可以獲得一些靈活性 - 或者之後你可以通過普通的連接表關聯它們等等。

+0

感謝@NSGaga,這說明它非常好非常完整的答案! – SeanR

+0

不客氣肖恩 – NSGaga

0

不完全是一個答案,但我不明白爲什麼你需要一個位置的中間表。爲什麼不只是做:

public class Track 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int Position { get; set; } 
} 

public class Album 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<Track> Tracks { get; set; } 
} 
+0

關於在跟蹤實體中合併位置的好處。我是從許多回復到許多模型,其中軌道*可能*是在多張專輯,並試圖看看我能得到這個工作。這是不可能的情況嗎? – SeanR

+0

確保「多到多」的做法是有道理的,「最偉大的命中」式的專輯。我剛纔已經回答基礎上,OP標準問題,其中一個軌道被限制在一個專輯 – vidalsasoon