所以我正在关注这本书Entity Framework 6 Recipes
。我使用的是Visual Studio 2017
,.NET 4.6.1
和EF 6.2.0
。
我创建了这个简单的数据库结构:
CREATE TABLE Album
(
AlbumId INT IDENTITY(1,1) NOT NULL,
AlbumName NVARCHAR(100) NOT NULL,
CONSTRAINT [PK_Album] PRIMARY KEY CLUSTERED ([AlbumId] ASC)
)
CREATE TABLE Artist
(
ArtistId INT IDENTITY(1,1) NOT NULL,
FirstName NVARCHAR(100) NOT NULL,
MiddleName NVARCHAR(100) NOT NULL,
LastName NVARCHAR(100) NOT NULL,
CONSTRAINT [PK_Artist] PRIMARY KEY CLUSTERED (ArtistId ASC)
)
CREATE TABLE LinkTable
(
ArtistId INT NOT NULL,
AlbumId INT NOT NULL,
CONSTRAINT FK_LinkTable_Artist FOREIGN KEY (ArtistId) REFERENCES dbo.Artist (ArtistId),
CONSTRAINT FK_LinkTable_Album FOREIGN KEY (AlbumId) REFERENCES dbo.Album (AlbumId)
)
ALTER TABLE LinkTable ADD CONSTRAINT PK_LinkTable PRIMARY KEY (ArtistId, AlbumId)
在代码中我有这个:
static void Main(string[] args)
{
SeedMusicData();
ListMusicData();
}
问题是当我尝试将新记录添加到数据库时。如果在SeedMusicData()
我有这个:
private static void SeedMusicData()
{
using (var context = new MusicEntities())
{
var artist = new Artist { FirstName = "Alan", LastName = "Jackson", MiddleName = "X." };
var album1 = new Album { AlbumName = "Drive" };
var album2 = new Album { AlbumName = "Live at Texas stadium" };
artist.Albums.Add(album1);
artist.Albums.Add(album2);
context.Artists.Add(artist);
context.SaveChanges();
}
}
然后一切正常,数据存储在数据库中。
但是,如果我尝试这样做:
private static void SeedMusicData()
{
using (var context = new MusicEntities())
{
var artist1 = new Artist { FirstName ="Tobby", LastName = "Keith", MiddleName = "Y." };
var artist2 = new Artist { FirstName = "Merle", LastName = "Haggard", MiddleName = "Z." };
var album = new Album { AlbumName = "Hokytonk University"};
artist1.Albums.Add(album);
artist2.Albums.Add(album);
context.Albums.Add(album); //use Albums instead Artists when it works
context.SaveChanges();
}
}
然后没有任何东西存储在数据库中,我也没有得到某种异常。而且我认为除了这个之外,我正在按照这本书的方式来阅读这本书:
ALTER TABLE LinkTable ADD CONSTRAINT PK_LinkTable PRIMARY KEY (ArtistId, AlbumId)
由于我收到的错误似乎是由于缺少连接表的主键而造成的,并且在添加错误之后修复了错误。但我想知道这是否可能是问题的原因。
P.S
所以一些额外的信息:
这是模型在VS设计器中的外观:
在Music.tt
里面我有:
Album.cs:
public partial class Album
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Album()
{
this.Artists = new HashSet<Artist>();
}
public int AlbumId { get; set; }
public string AlbumName { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Artist> Artists { get; set; }
}
和Artist.cs:
public partial class Artist
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Artist()
{
this.Albums = new HashSet<Album>();
}
public int ArtistId { get; set; }
public string FirstName { get; set; }
public string MiddletName { get; set; }
public string LastName { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Album> Albums { get; set; }
}
联结表位于DataBase中,但根据我的理解,如果只包含两个外键,EF不会包含它。
答案 0 :(得分:1)
在SeedMusicData中,将艺术家添加到相册,而不是将相册添加到艺术家。
album.Artist.Add(artist1);
album.Artist.Add(artist2);
context.Album.Add(album);
context.SaveChanges();
当你添加相册时,它还会带来#34; SaveChanges期间的艺术家。
更新:如果需要,可以在SaveChanges之前检查实体的状态:
var s1 = context.Entry(artist1).State;
var s2 = context.Entry(artist2).State;
var sx = context.Entry(album).State;
如果您将艺术家添加到相册,则所有条目都将标记为&#34;已添加&#34;。如果您将相册添加到艺术家,相册条目将标记为&#34;添加&#34;但艺术家的作品将标记为&#34; Detached&#34;。 SaveChanges不会处理分离的条目,导致数据库更新不完整。