简体   繁体   English

EF多对多关系未添加实体之一的记录

[英]EF many to many relationship is not adding records for one of the entities

So I'm following the book Entity Framework 6 Recipes . 因此,我正在关注Entity Framework 6 Recipes一书。 I am using Visual Studio 2017 , .NET 4.6.1 and EF 6.2.0 . 我正在使用Visual Studio 2017.NET 4.6.1EF 6.2.0

I've created this simple DB structure: 我创建了这个简单的数据库结构:

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)

and in the code I have this: 在代码中,我有这个:

static void Main(string[] args)
{
    SeedMusicData();    
    ListMusicData();
}

The problem is when I try to add new records to the database. 问题是当我尝试将新记录添加到数据库时。 If in the SeedMusicData() I have this: 如果在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();
    }
}

then everything works fine and the data is stored in the database. 然后一切正常,数据存储在数据库中。

However if I try to do it like this: 但是,如果我尝试这样做:

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();
    }
}

Then nothing is stored in the database, I don't get some sort of exception either. 然后什么也没有存储在数据库中,我也没有得到任何异常。 And I think I'm following the book literally except for this one: 而且我认为除了这本书,我实际上是在关注这本书:

ALTER TABLE LinkTable ADD CONSTRAINT PK_LinkTable PRIMARY KEY (ArtistId, AlbumId)

Since I was getting error which seemed to be caused by the lack of primary key for the junction table, and after adding one the error was fixed. 由于我收到的错误似乎是由联结表缺少主键引起的,因此添加错误后,该错误已得到解决。 But I wonder if this could be the cause of the problem. 但是我不知道这是否可能是问题的原因。

PS 聚苯乙烯

So some additional info: 所以一些附加信息:

This is how the model looks in VS designer: 这是模型在VS设计器中的外观:

音乐.edmx

And inside Music.tt I have: Music.tt我有:

Album.cs: 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; }
    }

And Artist.cs: 和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; }
    }

The junction table is in the DataBase but from what I understand it's expected for EF to not include it if it only contains the two Foreign Keys. 联结表位于数据库中,但是据我了解,如果EF仅包含两个外键,则不包括它。

In SeedMusicData, add artists to album instead of adding album to artist. 在SeedMusicData中,将艺术家添加到专辑,而不是将专辑添加到艺术家。

album.Artist.Add(artist1);
album.Artist.Add(artist2);
context.Album.Add(album);    
context.SaveChanges();

When you add album, it will also "bring" artists during SaveChanges. 当您添加专辑时,它还将在SaveChanges期间“带来”艺术家。

UPDATE: if you want, you can check the State of your entities before SaveChanges: 更新:如果需要,可以在SaveChanges之前检查实体的状态:

var s1 = context.Entry(artist1).State;
var s2 = context.Entry(artist2).State;
var sx = context.Entry(album).State;

If you add artists to the album, all the entries will be marked as "Added". 如果将艺术家添加到相册,所有条目将被标记为“已添加”。 If you add the album to artists, album entry will be marked as "Added" but artists entries will be marked as "Detached". 如果将专辑添加到艺术家,专辑条目将被标记为“已添加”,而艺术家条目将被标记为“已分离”。 Detached entries will be not processed by SaveChanges resulting in an incomplete database update. 保存的条目将不会被SaveChanges处理,从而导致数据库更新不完整。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM