Не проходит миграция

89
15 декабря 2021, 17:10

Всем доброго времени суток, опять проблема с миграциями бд, в проекте asp.net core EF добавил модель для создания связи многие ко многим между таблицей пользователей и таблицей фотографий, прописал в контексте все корректно на мой взгляд, делаю add-migration daaLikeTable, все идет хорошо и миграционный файл создается, затем ввожу update-database и получаю ошибку There is already an object named 'Files' in the database. Странно конечно, ошибка говорит что таблица Files уже создана, но в последней миграции отмечена только последняя таблица LikePhotos, т.е. апдейт как я понял обращается не к той миграции??? Ладно думаю, пойду другим путем, удаляю полностью бд, удаляю всю папку миграций, теперь весь код у меня собран и по идее, одной миграцией я должен записать и старые таблицы, и новые в один файл, и потом сделать апдейт, и тут уж все должно заработать, но когда я прописываю add-migration db то я получаю другую ошибку: Вот весь текст, что выдает консоль диспетчера пакетов:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Data.SqlClient.SqlException: Introducing FOREIGN KEY constraint 'FK_Friendships_Users_UserId' on table 'Friendships' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint or index. See previous errors. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource1 completion, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite, String methodName) at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary2 parameterValues) at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary2 parameterValues) at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary2 parameterValues) at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable1 migrationCommands, IRelationalConnection connection) at Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreator.CreateTables() at Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreator.EnsureCreated() at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.EnsureCreated() at webapplication.Models.DBUserContext..ctor() in C:\Users\Carskiy\source\repos\SWserv\webapplication\Models\DBUserContext.cs:line 17 --- End of inner exception stack trace --- at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor) at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean skipCheckThis, Boolean fillCache) at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions) at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass12_3.<FindContextTypes>b__13() at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func1 factory) at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_1.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action) Exception has been thrown by the target of an invocation.

в одной из прошлых тем я уже с этим сталкивался и мне сказали что это происходит из-за "Это вы наткнулись на ограничение самого SQL Server'а. EF тут ни причём." НО в прошлом проекте у меня была точно такая же таблица, точно так же оформлена в плане только модели другие, а все остальное сделано идентично, и там с миграциями и бд проблем вовсе не возникало(( И еще странно, почему когда я делаю миграцию именно на таблицу LikePhoto, она проходит без проблем, а вот если на все сразу, то получается ошибка(( Очень прошу помочь люди, вторые сутки сижу, не ем не пью не сплю, сделать надо, а все что перепробовал, ничего не помогает. пока решил это так - убираю весь новый код, делаю миграцию и создаю бд с таблицами, потом опять добавляю новый код, и вручную создаю таблицу в бд и пишу всю ее логику сам, но так не пойдет, необходимо чтобы все работало именно с миграций и апдейтов как у людей... Очень прошу помощи... Теперь по коду- Сущность юзера:

public class User
    {
        public User()
        {
            UserFriends = new List<Friends>();
            UserPosts = new List<UserPost>();
            LikePhotos = new List<LikePhoto>();//Вот этот список
        }
        public int Id { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public string City { get; set; }

        public string AvatarImgPath { get; set; }
        public List<UserPost> UserPosts { get; set; }
        public List<Photo> Photos { get; set; }
        public List<Friends> UserFriends { get; set; }
        public List<Friends> WhoAddMe { get; set; }
        public List<LikePhoto> LikePhotos { get; set; }//Вот этот список
    }

Сущность фото

public class Photo
    {
        public Photo()
        {           
            LikePhotos = new List<LikePhoto>();
        }

        public int Id { get; set; }
        public string PhotoPath { get; set; }
        public int UserId { get; set; }
        public User User { get; set; }
        public List<LikePhoto> LikePhotos { get; set; }
    }

Объединяющая сущность

public class LikePhoto
    {
        public int UserId { get; set; }
        public User User { get; set; }
        public int PhotoId { get; set; }
        public Photo Photo { get; set; }
    }

Контекст

modelBuilder.Entity<LikePhoto>()
                .HasKey(t => new { t.UserId, t.PhotoId });
            modelBuilder.Entity<LikePhoto>()
                .HasOne(sc => sc.User)
                .WithMany(s => s.LikePhotos)
                .HasForeignKey(sc => sc.UserId);
            modelBuilder.Entity<LikePhoto>()
                .HasOne(sc => sc.Photo)
                .WithMany(c => c.LikePhotos)
                .HasForeignKey(sc => sc.PhotoId);
        }
Answer 1

Все дело в каскадировании полей, снял каскадирование с нужных мне полей, и все заработало, вот результат

modelBuilder.Entity<LikePhoto>()
                .HasKey(t => new { t.UserId, t.PhotoId });
            modelBuilder.Entity<LikePhoto>()
                .HasOne(sc => sc.Photo)
                .WithMany(c => c.LikePhotos)
                .HasForeignKey(sc => sc.PhotoId);               
            modelBuilder.Entity<LikePhoto>()
                .HasOne(sc => sc.User)
                .WithMany(s => s.LikePhotos)
                .HasForeignKey(sc => sc.UserId)
                .OnDelete(DeleteBehavior.Restrict);//вот это сработало!!! 
READ ALSO
Получить свойство наследника

Получить свойство наследника

У меня есть абстрактный класс со своими свойствами

126
Как кратко инициализировать объекты

Как кратко инициализировать объекты

Как то можно саму инициализацию объектов переписать в меньшое количество строк?

138
Могу ли я создавать элементы визуального интерфейса в MVVM

Могу ли я создавать элементы визуального интерфейса в MVVM

Могу ли я создавать элементы визуального интерфейса в MVVM? Допустим у меня по нажатию кнопки "+" появляется еще один TextBoxКак это прописать во VM?

195