Entity Framework Core:关系表多对多 - 插入现有数据

问题描述 投票:0回答:1

我尝试插入关系数据(一些数据已经存在于我的数据库中)。如何根据我现有的类别和心情创作音乐?

我收到此错误:

Microsoft.EntityFrameworkCore.DbUpdateException:保存实体更改时发生错误。有关详细信息,请参阅内部异常。

Npgsql.PostgresException(0x80004005):23505:重复的键值违反了唯一约束“PK_AgeRates”

详细信息:详细信息已被编辑,因为它可能包含敏感数据。在连接字符串中指定“包含错误详细信息”以包含此信息。`

实体

AgeRateUpdated

现有数据:

我的代码:

public record Command(CreateMusicRequest Model) : ICommand<Response<CreatedMusicResponse>>;

public class CommandHandler : ICommandHandler<Command, Response<CreatedMusicResponse>>
{
    private readonly IGenericRepository<Music> _musicRepositoryAsync;
    private readonly IGenericRepository<Category> _categoryRepositoryAsync;
    private readonly IGenericRepository<Mood> _moodRepositoryAsync;
    public readonly IGenericRepository<AgeRate> _ageRateRepositoryAsync;
    private readonly IUnitOfWork _unitOfWork;

    public CommandHandler(IGenericRepository<Music> musicRepositoryAsync,
          IGenericRepository<Category> categoryRepositoryAsync, 
          IGenericRepository<Mood> moodRepositoryAsync,
          IGenericRepository<AgeRate> ageRateRepositoryAsync,
          IUnitOfWork unitOfWork)
    {
        _musicRepositoryAsync = musicRepositoryAsync;
        _categoryRepositoryAsync = categoryRepositoryAsync;
        _moodRepositoryAsync = moodRepositoryAsync;
        _unitOfWork = unitOfWork;
        _ageRateRepositoryAsync = ageRateRepositoryAsync;
    }

    public async Task<Response<CreatedMusicResponse>> Handle(Command request, CancellationToken cancellationToken)
    {
        Music music = new()
              {
                  Name = request.Model.Name,
                  ImageUrl = request.Model.ImageUrl,
                  IsUsable = request.Model.IsUsable,
                  Lyrics=request.Model.Lyrics
              };

        music.AgeRate = await _ageRateRepositoryAsync.GetAsync(x => x.Id == request.Model.AgeRateId);

        foreach (var moodId in request.Model.MoodIds)
        {
            Mood existMood = await _moodRepositoryAsync.GetAsync(x => x.Id == moodId);

            if (existMood != null)
            {
                music.Moods.Add(existMood);
            }
        }

        foreach (var categoryId in request.Model.CategoryIds)
        {
            Category existCategory = await _categoryRepositoryAsync.GetAsync(x => x.Id == categoryId);

            if (existCategory != null)
            {
                music.Categories.Add(existCategory);
            }
       }

       await _musicRepositoryAsync.CreateAsync(music);
       await _unitOfWork.CommitAsync();

       return Response<CreatedMusicResponse>.Success(music.Adapt<CreatedMusicResponse>(), 201);
    }
}

EF Core 7,多对多关系

public class MyDbContext : IdentityDbContext<IdentityUser, IdentityRole, string>
{
    public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
    {

    }
    public DbSet<Music> Musics { get; set; }
    public DbSet<AgeRate> AgeRates { get; set; }
    public DbSet<Mood> Moods { get; set; }
    public DbSet<Category> Categories { get; set; }


    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<Music>().Navigation(m => m.Moods).AutoInclude();
        builder.Entity<Music>().Navigation(c => c.Categories).AutoInclude();
        builder.Entity<Music>().Navigation(c => c.AgeRate).AutoInclude();
        base.OnModelCreating(builder);
    }
}```
.net asp.net-mvc entity-framework asp.net-core entity-framework-core
1个回答
0
投票

根据文档可以简单地解释多对多关系https://learn.microsoft.com/en-us/ef/core/modeling/relationships/many-to-many#examples

我的样本已简化

public class Music
{
    …
    public int MusicID { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    public virtual ICollection<Category> Categories { get; set; }
    public virtual ICollection<Mood> Moods { get; set; }
    public virtual ICollection<AgeRate> AgeRates { get; set; }
}

DbContext 中不需要自动包含

当需要与现有实体建立关系时,使用Add

public async Task<Music> ManyToMany()
{
    …
    //get the mood
    ICollection<Mood> moods = new List<Mood> {
    _context.Mood.FirstOrDefault(i => i.MoodID == request.Model.AgeRateId) };
    
    _context.Music.Add(new Music { Name = "MusicMoodName1", Url = "MusicMoodUrl1", Moods = moods });

    //same as category/agerate
    …
    _context.SaveChanges();
    …
}

关系表自动创建,执行后插入成功。

音乐桌

心情音乐桌

© www.soinside.com 2019 - 2024. All rights reserved.