EF多对多关系不会为其中一个实体添加记录

时间:2018-03-16 08:53:30

标签: c# entity-framework-6

所以我正在关注这本书Entity Framework 6 Recipes。我使用的是Visual Studio 2017.NET 4.6.1EF 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.edmx

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不会包含它。

1 个答案:

答案 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不会处理分离的条目,导致数据库更新不完整。