Sea*_*anR 4 entity-framework ef-code-first
我正在为音乐曲目和专辑建模,其中专辑有很多曲目,曲目只能在一个专辑中,并有一个连接表来指定它在专辑列表中的位置.
这是我的模特:
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; }
}
Run Code Online (Sandbox Code Playgroud)
和我的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);
}
}
Run Code Online (Sandbox Code Playgroud)
专辑和AlbumTracks之间的一对多关系很好,但除了预期之外
[AlbumTrackId] [int] NOT NULL,
Run Code Online (Sandbox Code Playgroud)
Code First不断添加
[AlbumTrack_AlbumId] [int] NOT NULL,
[AlbumTrack_TrackId] [int] NOT NULL
Run Code Online (Sandbox Code Playgroud)
到轨道表.
如何更好地建模Track to Album Track关系,以便只有我指定的属性在db字段中翻译?
[是的,在我的世界中,一首曲目只能存在于一张专辑中!]
谢谢.
Track根据建议,使位置成为有意义的一部分.
但是,如果你仍然希望你的"加入"表能够运作 - 而且我个人总是宁愿将这些专辑与他们的'协会',即职位等分开......
要做到这一点,你需要重新组织你的关系.EF/CF无法构建它 - 因为您要求它本身支持或预期的东西.加入,索引表总是期望另一方面的"多重性".
基本上,你
AlbumTrack不再是一个"加入"表-但仅仅是一个one-on-one与Track+你有Album从AlbumTrack 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; }
}
Run Code Online (Sandbox Code Playgroud)
......并且流畅的配置:
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);
Run Code Online (Sandbox Code Playgroud)
......你可以像以下一样使用它:
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();
Run Code Online (Sandbox Code Playgroud)
(或者你可以'添加'专辑曲目,其余的将进入).
注意:您不再需要复合键 - 因为您的AlbumTrack基本上只依赖于音轨 - 即您only one record对每个音轨都有- 要附加"专辑".
你也不需要// public int AlbumTrackId { get; set; }那个相反的一面,fk在专辑中.这也是旧设置中的错误(因为你需要fk的'两把钥匙' - 加入表).
而且,要补充一点,整个结构"建议"基本上你只是将"分割"轨道表 - 分成两个一对一的表 - 而且你也可以只使用Track/Album.但这有其自身的优势 - 虽然你有额外的连接和读/写(在缺点)你获得了一些灵活性 - 或者稍后你可以通过普通的连接表等关联它们.
| 归档时间: |
|
| 查看次数: |
5870 次 |
| 最近记录: |