0

I have a Net Core 3.1 MVC project where a Playlist can be created and added to an existing Team. I run in to problems when I try to save the Playlist entity with _context.Add(playlist) and then _context.SaveChangesAsync() with the following error:

Cannot insert duplicate key row in object 'dbo.Teams' with unique index 'IX_Teams_TeamName'. The duplicate key value is (Team Name Four).
The statement has been terminated.

My code:

PlaylistDTO dto = new PlaylistDTO();
dto.Name = "new playlist with related team";
dto.Team = _context.Team.FirstOrDefault(t => t.Id == id) // id comes from viewmodel
Playlist storeToDb = _mapper.Map<Playlist>(dto)
_context.Playlists.Add(storeToDb);
                    
await _context.SaveChangesAsync(); // throws error cannot insert duplicates. 

My entities:

public class Playlist: AuditEntity
{
    // id comes from AuditEntity
    public string PlayListName { get; set; }
    public string Description { get; set; }

    public Team Team { get; set; }
}

public class Team: AuditEntity
{
    // id comes from AuditEntity
    public string TeamName {get; set; }
    // other properties, including other related entities
    public ICollection<Playlist> Playlists {get; set;}
}

My DbConfig file

public class TeamDbConfig : IEntityTypeConfiguration<Team>
{
    public void Configure(EntityTypeBuilder<Team> builder)
    {
        builder.ToTable("Teams");

        builder.HasIndex(t => t.TeamName)
            .IsUnique();

        // one2many rel for playlist. One team can have multiple playlists
        builder.HasMany(t => t.Playlists)
            .WithOne(pl => pl.Team)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.Restrict);
            
    }
}

In a similar post it was explained that with .Add() EF will treat any objects as new (and so it cannot add an entity with restricted columns twice). However, I don't know how to get this to work. Loading it untracked vs tracked, setting the Entry().EntityState to Modified or Unchanged doesn't seem to do anything.

This seems to be a pretty standard thing to do, yet I cannot get it done. So, I have a few questions:

  • Given what I want (a user can add an existing team to a new playlist), do I have the correct relationships defined between Team and Playlist?
  • What do I need to use as a statement instead (or in addition to) the Add() statement that I now have?
3
  • Can you post the real code pls? It is vital if you want to get help. You have posted _context.Playlists.Add(storeToDb); but storeToDb is not even defined. Commented Oct 16, 2021 at 21:35
  • 1
    The error is not about id by the way, error says unique index (Name column) is violated. And where you configure primary key (Id column?) for your Team entity? Commented Oct 16, 2021 at 21:36
  • 1
    What happens in _mapper.Map<Playlist>(dto)? It seems that there a new Team object is created. Commented Oct 17, 2021 at 9:24

1 Answer 1

1

Since you are using net 3.1 you have to add TeamId to

public class Playlist: AuditEntity
{
    // id comes from AuditEntity
    public string PlayListName { get; set; }
    public string Description { get; set; }

     public int? TeamId { get; set; }
    [ForeignKey(nameof(TeamId))]
    [InverseProperty("Playlists")]
    public virtual Team Team { get; set; }
}

public class Team: AuditEntity
{
    // id comes from AuditEntity
    public string TeamName {get; set; }
    // other properties, including other related entities

    [InverseProperty(nameof(Playlist.Team))]
    public ICollection<Playlist> Playlists {get; set;}
}

[InverseProperty(nameof(FirstClass.SecondClass))]


modelBuilder.Entity<PlayList>(entity =>
            {
                entity.HasOne(d => d.Team)
                   .WithMany(p => p.Playlists)
                   .HasForeignKey(d => d.TeamId);
            });

and use it to assign to playlist

PlaylistDTO dto = new PlaylistDTO();
dto.Name = "new playlist with related team";
dto.TeamId=id;  // id comes from viewmodel

Playlist storeToDb = _mapper.Map<Playlist>(dto)
_context.Playlists.Add(storeToDb);
await _context.SaveChangesAsync();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.