Share the entity model between Database and the test database via ModelConfiguration
This commit is contained in:
@@ -6,7 +6,6 @@ using Musify.Application.Contracts;
|
|||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
using Musify.Domain.ValueObjects;
|
using Musify.Domain.ValueObjects;
|
||||||
using Musify.Infrastructure.Configuration;
|
using Musify.Infrastructure.Configuration;
|
||||||
using Musify.Infrastructure.MassTransit.Sagas;
|
|
||||||
using Npgsql;
|
using Npgsql;
|
||||||
|
|
||||||
namespace Musify.Infrastructure.Persistence;
|
namespace Musify.Infrastructure.Persistence;
|
||||||
@@ -31,144 +30,7 @@ public class Database(DatabaseConfiguration configuration)
|
|||||||
modelBuilder.AddOutboxMessageEntity();
|
modelBuilder.AddOutboxMessageEntity();
|
||||||
modelBuilder.AddOutboxStateEntity();
|
modelBuilder.AddOutboxStateEntity();
|
||||||
|
|
||||||
var trackProcessing = modelBuilder.Entity<TrackProcessingState>();
|
ModelConfiguration.Apply(modelBuilder);
|
||||||
trackProcessing.HasKey(state => state.CorrelationId);
|
|
||||||
trackProcessing.Property(state => state.CorrelationId).ValueGeneratedNever();
|
|
||||||
trackProcessing.Property(state => state.CurrentState).HasMaxLength(64);
|
|
||||||
|
|
||||||
modelBuilder.Entity<Track>()
|
|
||||||
.OwnsOne(track => track.Pictures, pictures =>
|
|
||||||
{
|
|
||||||
pictures.Property(p => p.OriginalName).HasColumnName("OriginalPictureName").HasMaxLength(64);
|
|
||||||
pictures.Property(p => p.SmallName).HasColumnName("SmallPictureName").HasMaxLength(64);
|
|
||||||
pictures.Property(p => p.MediumName).HasColumnName("MediumPictureName").HasMaxLength(64);
|
|
||||||
pictures.Property(p => p.LargeName).HasColumnName("LargePictureName").HasMaxLength(64);
|
|
||||||
pictures.Property(p => p.ProcessingStatus).HasColumnName("PicturesProcessingStatus");
|
|
||||||
});
|
|
||||||
modelBuilder.Entity<Track>().Navigation(track => track.Pictures).IsRequired();
|
|
||||||
|
|
||||||
modelBuilder.Entity<Track>()
|
|
||||||
.OwnsOne(track => track.Audio, audio =>
|
|
||||||
{
|
|
||||||
audio.Property(a => a.OriginalName).HasColumnName("OriginalAudioName").HasMaxLength(64);
|
|
||||||
audio.Property(a => a.FolderName).HasColumnName("AudioFolderName").HasMaxLength(64);
|
|
||||||
audio.Property(a => a.TranscodeStatus).HasColumnName("AudioTranscodeProcessingStatus");
|
|
||||||
});
|
|
||||||
modelBuilder.Entity<Track>().Navigation(track => track.Audio).IsRequired();
|
|
||||||
|
|
||||||
modelBuilder.Entity<Track>()
|
|
||||||
.HasOne(track => track.Owner)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(track => track.OwnerUserId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<PlayList>()
|
|
||||||
.Property(playList => playList.Visibility)
|
|
||||||
.HasDefaultValue(PlayListVisibility.Private);
|
|
||||||
|
|
||||||
modelBuilder.Entity<PlayList>()
|
|
||||||
.OwnsOne(playList => playList.Pictures, pictures =>
|
|
||||||
{
|
|
||||||
pictures.Property(p => p.OriginalName).HasColumnName("OriginalPictureName").HasMaxLength(64).IsRequired(false);
|
|
||||||
pictures.Property(p => p.SmallName).HasColumnName("SmallPictureName").HasMaxLength(64).IsRequired(false);
|
|
||||||
pictures.Property(p => p.MediumName).HasColumnName("MediumPictureName").HasMaxLength(64).IsRequired(false);
|
|
||||||
pictures.Property(p => p.LargeName).HasColumnName("LargePictureName").HasMaxLength(64).IsRequired(false);
|
|
||||||
});
|
|
||||||
modelBuilder.Entity<PlayList>().Navigation(playList => playList.Pictures).IsRequired(false);
|
|
||||||
|
|
||||||
modelBuilder.Entity<Album>()
|
|
||||||
.OwnsOne(album => album.Pictures, pictures =>
|
|
||||||
{
|
|
||||||
pictures.Property(p => p.OriginalName).HasColumnName("OriginalPictureName").HasMaxLength(64);
|
|
||||||
pictures.Property(p => p.SmallName).HasColumnName("SmallPictureName").HasMaxLength(64).IsRequired(false);
|
|
||||||
pictures.Property(p => p.MediumName).HasColumnName("MediumPictureName").HasMaxLength(64).IsRequired(false);
|
|
||||||
pictures.Property(p => p.LargeName).HasColumnName("LargePictureName").HasMaxLength(64).IsRequired(false);
|
|
||||||
});
|
|
||||||
modelBuilder.Entity<Album>().Navigation(album => album.Pictures).IsRequired(false);
|
|
||||||
|
|
||||||
modelBuilder.Entity<Album>()
|
|
||||||
.HasOne(album => album.Owner)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(album => album.OwnerUserId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<AlbumHasTrack>()
|
|
||||||
.HasOne(albumTrack => albumTrack.Album)
|
|
||||||
.WithMany(album => album.AlbumTracks)
|
|
||||||
.HasForeignKey(albumTrack => albumTrack.AlbumId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<AlbumHasTrack>()
|
|
||||||
.HasOne(albumTrack => albumTrack.Track)
|
|
||||||
.WithMany(track => track.AlbumTracks)
|
|
||||||
.HasForeignKey(albumTrack => albumTrack.TrackId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<AlbumHasTrack>()
|
|
||||||
.HasIndex(albumTrack => new { albumTrack.AlbumId, albumTrack.TrackId })
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
modelBuilder.Entity<PlayListHasTrack>()
|
|
||||||
.HasIndex(playListTrack => new { playListTrack.PlayListId, playListTrack.TrackId })
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
modelBuilder.Entity<Mix>()
|
|
||||||
.HasIndex(mix => new { mix.UserId, mix.Position });
|
|
||||||
|
|
||||||
modelBuilder.Entity<MixItem>()
|
|
||||||
.HasOne(item => item.Mix)
|
|
||||||
.WithMany(mix => mix.Items)
|
|
||||||
.HasForeignKey(item => item.MixId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<MixItem>()
|
|
||||||
.HasOne(item => item.Track)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(item => item.TrackId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<MixItem>()
|
|
||||||
.HasIndex(item => new { item.MixId, item.Position });
|
|
||||||
|
|
||||||
modelBuilder.Entity<TrackLike>()
|
|
||||||
.HasIndex(like => new { like.UserId, like.TrackId })
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
modelBuilder.Entity<TrackTag>()
|
|
||||||
.HasOne(trackTag => trackTag.Track)
|
|
||||||
.WithMany(track => track.Tags)
|
|
||||||
.HasForeignKey(trackTag => trackTag.TrackId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<TrackTag>()
|
|
||||||
.HasIndex(trackTag => new { trackTag.TrackId, trackTag.Tag })
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
modelBuilder.Entity<UserFollow>()
|
|
||||||
.HasOne(follow => follow.Follower)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(follow => follow.FollowerId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<UserFollow>()
|
|
||||||
.HasOne(follow => follow.Followed)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(follow => follow.FollowedId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<UserFollow>()
|
|
||||||
.HasIndex(follow => new { follow.FollowerId, follow.FollowedId })
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
var playListProcessing = modelBuilder.Entity<PlayListProcessingState>();
|
|
||||||
playListProcessing.HasKey(state => state.CorrelationId);
|
|
||||||
playListProcessing.Property(state => state.CorrelationId).ValueGeneratedNever();
|
|
||||||
playListProcessing.Property(state => state.CurrentState).HasMaxLength(64);
|
|
||||||
|
|
||||||
var albumProcessing = modelBuilder.Entity<AlbumProcessingState>();
|
|
||||||
albumProcessing.HasKey(state => state.CorrelationId);
|
|
||||||
albumProcessing.Property(state => state.CorrelationId).ValueGeneratedNever();
|
|
||||||
albumProcessing.Property(state => state.CurrentState).HasMaxLength(64);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DbSet<User> Users => Set<User>();
|
public DbSet<User> Users => Set<User>();
|
||||||
|
|||||||
@@ -0,0 +1,154 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Musify.Domain.Entities;
|
||||||
|
using Musify.Domain.ValueObjects;
|
||||||
|
using Musify.Infrastructure.MassTransit.Sagas;
|
||||||
|
|
||||||
|
namespace Musify.Infrastructure.Persistence;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Entity model shared by <see cref="Database"/> and the in-memory test database, so both always agree.
|
||||||
|
/// </summary>
|
||||||
|
public static class ModelConfiguration
|
||||||
|
{
|
||||||
|
public static void Apply(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
var trackProcessing = modelBuilder.Entity<TrackProcessingState>();
|
||||||
|
trackProcessing.HasKey(state => state.CorrelationId);
|
||||||
|
trackProcessing.Property(state => state.CorrelationId).ValueGeneratedNever();
|
||||||
|
trackProcessing.Property(state => state.CurrentState).HasMaxLength(64);
|
||||||
|
|
||||||
|
modelBuilder.Entity<Track>()
|
||||||
|
.OwnsOne(track => track.Pictures, pictures =>
|
||||||
|
{
|
||||||
|
pictures.Property(p => p.OriginalName).HasColumnName("OriginalPictureName").HasMaxLength(64);
|
||||||
|
pictures.Property(p => p.SmallName).HasColumnName("SmallPictureName").HasMaxLength(64);
|
||||||
|
pictures.Property(p => p.MediumName).HasColumnName("MediumPictureName").HasMaxLength(64);
|
||||||
|
pictures.Property(p => p.LargeName).HasColumnName("LargePictureName").HasMaxLength(64);
|
||||||
|
pictures.Property(p => p.ProcessingStatus).HasColumnName("PicturesProcessingStatus");
|
||||||
|
});
|
||||||
|
modelBuilder.Entity<Track>().Navigation(track => track.Pictures).IsRequired();
|
||||||
|
|
||||||
|
modelBuilder.Entity<Track>()
|
||||||
|
.OwnsOne(track => track.Audio, audio =>
|
||||||
|
{
|
||||||
|
audio.Property(a => a.OriginalName).HasColumnName("OriginalAudioName").HasMaxLength(64);
|
||||||
|
audio.Property(a => a.FolderName).HasColumnName("AudioFolderName").HasMaxLength(64);
|
||||||
|
audio.Property(a => a.TranscodeStatus).HasColumnName("AudioTranscodeProcessingStatus");
|
||||||
|
});
|
||||||
|
modelBuilder.Entity<Track>().Navigation(track => track.Audio).IsRequired();
|
||||||
|
|
||||||
|
modelBuilder.Entity<Track>()
|
||||||
|
.HasOne(track => track.Owner)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey(track => track.OwnerUserId)
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
modelBuilder.Entity<PlayList>()
|
||||||
|
.Property(playList => playList.Visibility)
|
||||||
|
.HasDefaultValue(PlayListVisibility.Private);
|
||||||
|
|
||||||
|
modelBuilder.Entity<PlayList>()
|
||||||
|
.OwnsOne(playList => playList.Pictures, pictures =>
|
||||||
|
{
|
||||||
|
pictures.Property(p => p.OriginalName).HasColumnName("OriginalPictureName").HasMaxLength(64).IsRequired(false);
|
||||||
|
pictures.Property(p => p.SmallName).HasColumnName("SmallPictureName").HasMaxLength(64).IsRequired(false);
|
||||||
|
pictures.Property(p => p.MediumName).HasColumnName("MediumPictureName").HasMaxLength(64).IsRequired(false);
|
||||||
|
pictures.Property(p => p.LargeName).HasColumnName("LargePictureName").HasMaxLength(64).IsRequired(false);
|
||||||
|
});
|
||||||
|
modelBuilder.Entity<PlayList>().Navigation(playList => playList.Pictures).IsRequired(false);
|
||||||
|
|
||||||
|
modelBuilder.Entity<Album>()
|
||||||
|
.OwnsOne(album => album.Pictures, pictures =>
|
||||||
|
{
|
||||||
|
pictures.Property(p => p.OriginalName).HasColumnName("OriginalPictureName").HasMaxLength(64);
|
||||||
|
pictures.Property(p => p.SmallName).HasColumnName("SmallPictureName").HasMaxLength(64).IsRequired(false);
|
||||||
|
pictures.Property(p => p.MediumName).HasColumnName("MediumPictureName").HasMaxLength(64).IsRequired(false);
|
||||||
|
pictures.Property(p => p.LargeName).HasColumnName("LargePictureName").HasMaxLength(64).IsRequired(false);
|
||||||
|
});
|
||||||
|
modelBuilder.Entity<Album>().Navigation(album => album.Pictures).IsRequired(false);
|
||||||
|
|
||||||
|
modelBuilder.Entity<Album>()
|
||||||
|
.HasOne(album => album.Owner)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey(album => album.OwnerUserId)
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
modelBuilder.Entity<AlbumHasTrack>()
|
||||||
|
.HasOne(albumTrack => albumTrack.Album)
|
||||||
|
.WithMany(album => album.AlbumTracks)
|
||||||
|
.HasForeignKey(albumTrack => albumTrack.AlbumId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
modelBuilder.Entity<AlbumHasTrack>()
|
||||||
|
.HasOne(albumTrack => albumTrack.Track)
|
||||||
|
.WithMany(track => track.AlbumTracks)
|
||||||
|
.HasForeignKey(albumTrack => albumTrack.TrackId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
modelBuilder.Entity<AlbumHasTrack>()
|
||||||
|
.HasIndex(albumTrack => new { albumTrack.AlbumId, albumTrack.TrackId })
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
modelBuilder.Entity<PlayListHasTrack>()
|
||||||
|
.HasIndex(playListTrack => new { playListTrack.PlayListId, playListTrack.TrackId })
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
modelBuilder.Entity<Mix>()
|
||||||
|
.HasIndex(mix => new { mix.UserId, mix.Position });
|
||||||
|
|
||||||
|
modelBuilder.Entity<MixItem>()
|
||||||
|
.HasOne(item => item.Mix)
|
||||||
|
.WithMany(mix => mix.Items)
|
||||||
|
.HasForeignKey(item => item.MixId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
modelBuilder.Entity<MixItem>()
|
||||||
|
.HasOne(item => item.Track)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey(item => item.TrackId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
modelBuilder.Entity<MixItem>()
|
||||||
|
.HasIndex(item => new { item.MixId, item.Position });
|
||||||
|
|
||||||
|
modelBuilder.Entity<TrackLike>()
|
||||||
|
.HasIndex(like => new { like.UserId, like.TrackId })
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
modelBuilder.Entity<TrackTag>()
|
||||||
|
.HasOne(trackTag => trackTag.Track)
|
||||||
|
.WithMany(track => track.Tags)
|
||||||
|
.HasForeignKey(trackTag => trackTag.TrackId)
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
modelBuilder.Entity<TrackTag>()
|
||||||
|
.HasIndex(trackTag => new { trackTag.TrackId, trackTag.Tag })
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
modelBuilder.Entity<UserFollow>()
|
||||||
|
.HasOne(follow => follow.Follower)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey(follow => follow.FollowerId)
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
modelBuilder.Entity<UserFollow>()
|
||||||
|
.HasOne(follow => follow.Followed)
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey(follow => follow.FollowedId)
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
modelBuilder.Entity<UserFollow>()
|
||||||
|
.HasIndex(follow => new { follow.FollowerId, follow.FollowedId })
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
var playListProcessing = modelBuilder.Entity<PlayListProcessingState>();
|
||||||
|
playListProcessing.HasKey(state => state.CorrelationId);
|
||||||
|
playListProcessing.Property(state => state.CorrelationId).ValueGeneratedNever();
|
||||||
|
playListProcessing.Property(state => state.CurrentState).HasMaxLength(64);
|
||||||
|
|
||||||
|
var albumProcessing = modelBuilder.Entity<AlbumProcessingState>();
|
||||||
|
albumProcessing.HasKey(state => state.CorrelationId);
|
||||||
|
albumProcessing.Property(state => state.CorrelationId).ValueGeneratedNever();
|
||||||
|
albumProcessing.Property(state => state.CurrentState).HasMaxLength(64);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Core\Musify.Domain\Domain.csproj" />
|
<ProjectReference Include="..\..\Core\Musify.Domain\Domain.csproj" />
|
||||||
<ProjectReference Include="..\..\Core\Musify.Application\Application.csproj" />
|
<ProjectReference Include="..\..\Core\Musify.Application\Application.csproj" />
|
||||||
|
<ProjectReference Include="..\..\Core\Musify.Infrastructure\Infrastructure.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Microsoft.Data.Sqlite;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Musify.Application.Contracts;
|
using Musify.Application.Contracts;
|
||||||
using Musify.Domain.Entities;
|
using Musify.Domain.Entities;
|
||||||
|
using Musify.Infrastructure.Persistence;
|
||||||
|
|
||||||
namespace Musify.Application.Tests.TestSupport;
|
namespace Musify.Application.Tests.TestSupport;
|
||||||
|
|
||||||
@@ -34,103 +35,7 @@ public sealed class TestDatabase : DbContext, IDatabase
|
|||||||
{
|
{
|
||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
|
|
||||||
modelBuilder.Entity<Track>().OwnsOne(track => track.Pictures);
|
ModelConfiguration.Apply(modelBuilder);
|
||||||
modelBuilder.Entity<Track>().Navigation(track => track.Pictures).IsRequired();
|
|
||||||
|
|
||||||
modelBuilder.Entity<Track>().OwnsOne(track => track.Audio);
|
|
||||||
modelBuilder.Entity<Track>().Navigation(track => track.Audio).IsRequired();
|
|
||||||
|
|
||||||
modelBuilder.Entity<Track>()
|
|
||||||
.HasOne(track => track.Owner)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(track => track.OwnerUserId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<PlayList>().OwnsOne(playList => playList.Pictures, pictures =>
|
|
||||||
{
|
|
||||||
pictures.Property(p => p.OriginalName).IsRequired(false);
|
|
||||||
pictures.Property(p => p.SmallName).IsRequired(false);
|
|
||||||
pictures.Property(p => p.MediumName).IsRequired(false);
|
|
||||||
pictures.Property(p => p.LargeName).IsRequired(false);
|
|
||||||
});
|
|
||||||
modelBuilder.Entity<PlayList>().Navigation(playList => playList.Pictures).IsRequired(false);
|
|
||||||
|
|
||||||
modelBuilder.Entity<Album>().OwnsOne(album => album.Pictures);
|
|
||||||
modelBuilder.Entity<Album>().Navigation(album => album.Pictures).IsRequired(false);
|
|
||||||
|
|
||||||
modelBuilder.Entity<Album>()
|
|
||||||
.HasOne(album => album.Owner)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(album => album.OwnerUserId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<AlbumHasTrack>()
|
|
||||||
.HasOne(albumTrack => albumTrack.Album)
|
|
||||||
.WithMany(album => album.AlbumTracks)
|
|
||||||
.HasForeignKey(albumTrack => albumTrack.AlbumId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<AlbumHasTrack>()
|
|
||||||
.HasOne(albumTrack => albumTrack.Track)
|
|
||||||
.WithMany(track => track.AlbumTracks)
|
|
||||||
.HasForeignKey(albumTrack => albumTrack.TrackId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<AlbumHasTrack>()
|
|
||||||
.HasIndex(albumTrack => new { albumTrack.AlbumId, albumTrack.TrackId })
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
modelBuilder.Entity<PlayListHasTrack>()
|
|
||||||
.HasIndex(playListTrack => new { playListTrack.PlayListId, playListTrack.TrackId })
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
modelBuilder.Entity<Mix>()
|
|
||||||
.HasIndex(mix => new { mix.UserId, mix.Position });
|
|
||||||
|
|
||||||
modelBuilder.Entity<MixItem>()
|
|
||||||
.HasOne(item => item.Mix)
|
|
||||||
.WithMany(mix => mix.Items)
|
|
||||||
.HasForeignKey(item => item.MixId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<MixItem>()
|
|
||||||
.HasOne(item => item.Track)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(item => item.TrackId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<MixItem>()
|
|
||||||
.HasIndex(item => new { item.MixId, item.Position });
|
|
||||||
|
|
||||||
modelBuilder.Entity<TrackLike>()
|
|
||||||
.HasIndex(like => new { like.UserId, like.TrackId })
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
modelBuilder.Entity<TrackTag>()
|
|
||||||
.HasOne(trackTag => trackTag.Track)
|
|
||||||
.WithMany(track => track.Tags)
|
|
||||||
.HasForeignKey(trackTag => trackTag.TrackId)
|
|
||||||
.OnDelete(DeleteBehavior.Cascade);
|
|
||||||
|
|
||||||
modelBuilder.Entity<TrackTag>()
|
|
||||||
.HasIndex(trackTag => new { trackTag.TrackId, trackTag.Tag })
|
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
modelBuilder.Entity<UserFollow>()
|
|
||||||
.HasOne(follow => follow.Follower)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(follow => follow.FollowerId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<UserFollow>()
|
|
||||||
.HasOne(follow => follow.Followed)
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey(follow => follow.FollowedId)
|
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
|
||||||
|
|
||||||
modelBuilder.Entity<UserFollow>()
|
|
||||||
.HasIndex(follow => new { follow.FollowerId, follow.FollowedId })
|
|
||||||
.IsUnique();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DbSet<User> Users => Set<User>();
|
public DbSet<User> Users => Set<User>();
|
||||||
|
|||||||
Reference in New Issue
Block a user