Добавление-миграция Entity Framework Core с абстрактным классом

Я пытаюсь научиться использовать миграцию Entity Framework Core, но получаю следующую ошибку:

Невозможно создать «DbContext» типа «». Исключение «Для типа сущности «Кино» не найден подходящий конструктор. Следующие конструкторы имели параметры, которые нельзя было привязать к свойствам типа сущности:

Невозможно связать «negativePoints», «positivePoints», «комментарии» в «Movie (int negativePoints, int позитивные точки, комментарии списка, заголовок строки, тип MediaType)»

Обратите внимание, что к параметрам конструктора можно привязать только сопоставленные свойства. Переходы к связанным сущностям, включая ссылки на принадлежащие им типы, не могут быть привязаны». был выброшен при попытке создать экземпляр. Информацию о различных шаблонах, поддерживаемых во время разработки, см. https://go.microsoft.com/fwlink/?linkid=851728

Насколько я понял и исследовал, невозможно выполнить процедуру Add-Migration с помощью абстрактных классов. Не могли бы вы подтвердить это или дать мне совет?

Я протестировал процедуру с помощью простого класса без использования Media, и у меня не возникло никаких проблем.

Это мой DbContext класс:

public class AppDbContext : DbContext
{
    public IConfiguration _config { get; set; }

    public AppDbContext(IConfiguration config)
    {
        _config = config;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(_config.GetConnectionString("DatabaseConnection"));
    }

    public DbSet<Movie> Movie { get; set; } 
    //public DbSet<Game> Game { get; set; }
    //public DbSet<User> User { get; set; }
}

Мой Media класс:

public abstract class Media
{
    public Guid Id { get; set; }
    public int? NegativePoints { get; set; }
    public int? PositivePoints { get; set; }
    public List<Comment>? Comments { get; set; }
    public string Title { get; set; }
    public MediaType Type { get; set; }

    public Media(int negativePoints, int positivePoints, List<Comment> comments, string title, MediaType type)
    {
        Id = new Guid();
        NegativePoints = negativePoints;
        PositivePoints = positivePoints;
        Comments = comments;
        Title = title;
        Type = Type;
    }
}

Мой Movie класс:

public class Movie : Media
{
    public string? Director { get; set; }
    public string? Genre { get; set; }
    public DateTime? Release { get; set; }
    public string? AgeRating { get; set; }
    public string? Synopsis { get; set; }
    public List<string>? Actors { get; set; }
    public TimeOnly? Duration { get; set; }
    public string? Language { get; set; }
    public string? ContryOrigin { get; set; }
    public string? ProductionStudio { get; set; }
    public string? Trailer { get; set; }

    public Movie(int negativePoints, int positivePoints, List<Comment> comments, string title, MediaType type) : base(negativePoints, positivePoints, comments, title, type)
    {
        Type = MediaType.Movie;
        Director = null;
        Genre = null;
        Release = null;
        AgeRating = null;
        Synopsis = null;
        Actors = new List<string>();
        Duration = null;
        Language = null;
        ContryOrigin = null;
        ProductionStudio = null;
        Trailer = null;
    }
}

Если у вас есть дополнительные предложения, я буду рад вас услышать.

Я использую .NET 8.0

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам нужен конструктор без параметров. Вашему абстрактному классу также понадобится конструктор без параметров.

public class Movie : Media
{
    public string? Director { get; set; }
    public string? Genre { get; set; }
    public DateTime? Release { get; set; }
    public string? AgeRating { get; set; }
    public string? Synopsis { get; set; }
    public List<string>? Actors { get; set; }
    public TimeOnly? Duration { get; set; }
    public string? Language { get; set; }
    public string? ContryOrigin { get; set; }
    public string? ProductionStudio { get; set; }
    public string? Trailer { get; set; }

    /*** ADD THIS HERE ***/
    public Movie(){
    }

    public Movie(int negativePoints, int positivePoints, List<Comment> comments, string title, MediaType type) : base(negativePoints, positivePoints, comments, title, type)
    {
        Type = MediaType.Movie;
        Director = null;
        Genre = null;
        Release = null;
        AgeRating = null;
        Synopsis = null;
        Actors = new List<string>();
        Duration = null;
        Language = null;
        ContryOrigin = null;
        ProductionStudio = null;
        Trailer = null;
    }
}

public abstract class Media
{
    public Guid Id { get; set; }
    public int? NegativePoints { get; set; }
    public int? PositivePoints { get; set; }
    public List<Comment>? Comments { get; set; }
    public string Title { get; set; }
    public MediaType Type { get; set; }

    /*** ADD THIS HERE ***/
    public Media(){
    }

    public Media(int negativePoints, int positivePoints, List<Comment> comments, string title, MediaType type)
    {
        Id = new Guid();
        NegativePoints = negativePoints;
        PositivePoints = positivePoints;
        Comments = comments;
        Title = title;
        Type = Type;
    }
}

Это не скомпилируется, поскольку у абстрактного класса нет конструктора без параметров. Ошибка не жалуется на параметры, она жалуется, что они не соответствуют сопоставленным свойствам класса.

Panagiotis Kanavos 17.04.2024 20:23

Спасибо за вашу поддержку, однако с предложенными изменениями компиляция, как указано выше, не принимается.

Tiago Dantas 17.04.2024 20:43

@TiagoDantas Я раньше этого не замечал. Вашему абстрактному классу также понадобится конструктор без параметров.

Xavier J 17.04.2024 21:09

@XavierJ Спасибо, с двумя пустыми конструкторами мне это удалось.

Tiago Dantas 17.04.2024 21:36

Я вижу несколько проблем с вашим кодом. Вы можете добавить миграцию, используя абстрактные классы.

В вашем медиа-классе

public abstract class Media
{
    public Guid Id { get; set; }
    public int? NegativePoints { get; set; }
    public int? PositivePoints { get; set; }
    public List<Comment>? Comments { get; set; }
    public string Title { get; set; }
    public MediaType Type { get; set; }

    public Media(int negativePoints, int positivePoints, List<Comment> comments, string title, MediaType type)
    {
        //Id = new Guid(); <-- try changing this to 
        Id = Guid.NewGuid();
        NegativePoints = negativePoints;
        PositivePoints = positivePoints;
        Comments = comments;
        Title = title;
        //Type = Type; <-- Change this to 
        Type=type //you are assigning the value to itself instead of the parameter value
    }

}

В конструкторе Movie вам больше не нужно назначать тип, поскольку вы присваиваете значение в базовом классе Media.

public Movie(int negativePoints, int positivePoints, List<Comment> comments, string title, MediaType type) : base(negativePoints, positivePoints, comments, title, type)
    {
        //Type = MediaType.Movie; <-- not needed assigned in base class (Media)
        Director = null;
        Genre = null;
        Release = null;
        AgeRating = null;
        Synopsis = null;
        Actors = new List<string>();
        Duration = null;
        Language = null;
        ContryOrigin = null;
        ProductionStudio = null;
        Trailer = null;
    }

Спасибо за вашу поддержку, но с предложенными изменениями у меня все еще есть проблема.

Tiago Dantas 17.04.2024 20:43

Другие вопросы по теме