我尝试插入关系数据(一些数据已经存在于我的数据库中)。如何根据我现有的类别和心情创作音乐?
我收到此错误:
Microsoft.EntityFrameworkCore.DbUpdateException:保存实体更改时发生错误。有关详细信息,请参阅内部异常。
Npgsql.PostgresException(0x80004005):23505:重复的键值违反了唯一约束“PK_AgeRates”
详细信息:详细信息已被编辑,因为它可能包含敏感数据。在连接字符串中指定“包含错误详细信息”以包含此信息。`
实体
现有数据:
我的代码:
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);
}
}```
根据文档可以简单地解释多对多关系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();
…
}
关系表自动创建,执行后插入成功。
音乐桌
心情音乐桌