Как исправить ошибку «Невозможно определить отношение, представленное свойством навигации» в Entity Framework

Когда я пытаюсь зарегистрировать пользователя на своем веб-сайте .NET Core 2.1 (используя удостоверение), я получаю следующую ошибку:

"InvalidOperationException: Unable to determine the relationship represented by navigation property 'City.ConnectionStartCity' of type 'ICollection'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.".

Причина, по которой это происходит, вероятно, не имеет ничего общего с идентификацией, но регистрация и вход в систему в настоящее время являются единственным способом, которым я знаю, как это вызвать.

Мне все еще нужны свойства «Город» и «ICollection» в моих классах, поэтому я не хочу использовать атрибут «[NotMapped]».

Я искал в Интернете и обнаружил, что это вызвано отношениями «многие-многие», но я чувствую, что это не так.

Класс «Соединение»:

public partial class Connection
    {
        public Connection()
        {
            ConnectionRoute = new HashSet<ConnectionRoute>();
        }

        public int Id { get; set; }
        public int StartCityId { get; set; }
        public int EndCityId { get; set; }
        public int AantalMinuten { get; set; }
        public double Prijs { get; set; }

        public Stad StartCity { get; set; }
        public Stad EndCity { get; set; }
        public ICollection<ConnectionRoute> ConnectionRoute{ get; set; }
    }

Класс «Город»:


public partial class City
    {
        public City()
        {
            AspNetUsers = new HashSet<AspNetUsers>();
            Hotel = new HashSet<Hotel>();
            ConnectionStartCity = new HashSet<Connection>();
            ConnectionEndCity= new HashSet<Connection>();
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public string Country { get; set; }

        public ICollection<AspNetUsers> AspNetUsers { get; set; }
        public ICollection<Hotel> Hotel { get; set; }
        public ICollection<Connection> ConnectionStartCity { get; set; }
        public ICollection<Connection> ConnectionEndCity { get; set; }
    }

Извлечение класса 'treinrittenContext' (dbContext):

public virtual DbSet<City> City{ get; set; }

public virtual DbSet<Connection> Connection{ get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            ...

            modelBuilder.Entity<City>(entity =>
            {
                entity.Property(e => e.Country)
                    .IsRequired()
                    .HasMaxLength(255)
                    .IsUnicode(false);

                entity.Property(e => e.Name)
                    .IsRequired()
                    .HasMaxLength(255)
                    .IsUnicode(false);

                entity.HasMany(p => p.ConnectionStartcity)
                    .WithOne(d => d.StartCity)
                    .HasForeignKey(d => d.StartCityId);

                entity.HasMany(p => p.ConnectionEndCity)
                    .WithOne(d => d.EndCity)
                    .HasForeignKey(d => d.EndCityId);
            });

            ...

            modelBuilder.Entity<Connection>(entity =>
            {
                entity.HasOne(d => d.StartCity)
                    .WithMany(p => p.ConnectionStartCity)
                    .HasForeignKey(d => d.StartCityId)
                    .OnDelete(DeleteBehavior.ClientSetNull)
                    .HasConstraintName("FK_Verbinding_BeginStad");

                entity.HasOne(d => d.EndCity)
                    .WithMany(p => p.ConnectionEndCity)
                    .HasForeignKey(d => d.EndCityId)
                    .OnDelete(DeleteBehavior.ClientSetNull)
                    .HasConstraintName("FK_Verbinding_EindStad");
            });

            ...
        }

Я ожидаю, что это сработает (поскольку в моих глазах это отношение «один ко многим»), но это не так.

Вы также должны подумать о своем именовании, коллекции должны быть множественными (meervoud), например, ваши DbSets должны быть Connections & Cities, а также ваши свойства ConnectionStartCity и ConnectionEndCity. Что касается ошибки, это может быть связано с тем, что вам не хватает аннотации [Required] в вашем StartCity и EndCity.

Dimitri 11.04.2019 11:52

@Dimitri, спасибо за совет по соглашению об именах. Добавление аннотаций [Required] к StartCity и EndCity в Connection не решило проблему.

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

Ответы 1

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

ОБНОВИТЬ

Здесь у вас есть несколько вариантов:

Вариант 1 с результатом 1

City Class becomes:

public partial class City
{
    public City()
    {           
        Connections = new HashSet<Connection>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public string Country { get; set; }

    public ICollection<Connection> Connections { get; set; }
}

Connection Class becomes:

public partial class Connection
{
    public Connection()
    {
    }

    public int Id { get; set; }

    public int StartCityId { get; set; }
    public int EndCityId { get; set; }

    public int AantalMinuten { get; set; }
    public double Prijs { get; set; }     
}

Your OnModelCreating becomes:

modelBuilder.Entity<City>().HasMany(city => city.Connections)
                           .WithRequired().HasForeignKey(con => con.EndCityId);

modelBuilder.Entity<City>().HasMany(city => city.Connections)
                           .WithRequired().HasForeignKey(con => con.StartCityId);

ИЛИ вы также можете сделать что-то подобное, что будет вариантом 2 с результатами 2:

City Class becomes:

public partial class City
{
    public City()
    {           
        Connections = new HashSet<Connection>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public string Country { get; set; }

    public ICollection<Connection> Connections { get; set; }
}

Connection Class becomes:

public partial class Connection
{
    public Connection()
    {
    }

    public int Id { get; set; }

    public virtual ICollection<City> Cities { get; set; }

    public int AantalMinuten { get; set; }
    public double Prijs { get; set; }     
}

И вам не нужно ничего делать в вашем OnModelCreating.

Я только что понял, что оставил некоторые слова непереведенными в своем вопросе. Это на мне извините! Я обновил его, так что теперь он должен иметь больше смысла. Город — это просто таблица для городов (в моем случае Лондон, Брюссель, ...), соединение должно быть соединением между двумя городами (например, «Лондон — Брюссель» или «Брюссель — Париж»). Итак, в City я хотел бы иметь список соединений, где город является отправной точкой, и список соединений, где город является конечной точкой. Полная модель базы данных (Stad = City и Verbinding = Connection): gyazo.com/8211bb2789e0f7a864aee1a6b9e21192

Lukas Nys 11.04.2019 14:08

Когда я пробую первый вариант, я получаю эту ошибку при построении: «Невозможно создать связь между« City.Connection »и« Connection.EndCity », потому что связь между« City.Connection »и« Conncection.StartCity » уже существует. . Свойства навигации могут участвовать только в одном отношении». Со вторым решением я теряю, какой город является отправной точкой, а какой — конечной. В этом случае важен их порядок.

Lukas Nys 11.04.2019 14:50

Коллекция Города должна быть виртуальной.

CrazyBaran 11.04.2019 15:02

Я согласен со вторым решением, неприменимым для вашего случая. Что касается ошибки, странно, не происходит на моей стороне. У вас включена миграция? Если это так, обновите свою модель. Если нет, можете ли вы показать мне, что у вас есть в onmodelcreating, и, в конце концов, как ваши классы выглядят сейчас?

Dimitri 11.04.2019 15:09

@Dimitri Ошибка, которую я получаю: gyazo.com/6f6c006ca3d6979bc4134590e363435c. Класс Город (Стад): gyazo.com/7f1dae57a8c33ef2d3a19f7879a956eb. Соединение класса (связывание): gyazo.com/1a4a9a8485ccabd5fba81a8f98eaef77. OnModelCreating (часть City = Stad): gyazo.com/75434895014a3d355b5770b6710cc9ae. OnModelCreating (часть Connection = Verbinding): gyazo.com/16c7d3d8894bb906ab0f30afee61e1f5

Lukas Nys 11.04.2019 15:28

@LukasNys Можете ли вы включить Entity ConnectionRoute (VerbindingRoute), пожалуйста?

Dimitri 11.04.2019 15:31

Маршрут подключения класса @Dimitri (VerbindingRoute): gyazo.com/5946a8d704e1bd491f287527f09edf70. OnModelCreating (часть ConnectionRoute): gyazo.com/c0485f0e04174daeb3e268720382c6a6.

Lukas Nys 11.04.2019 15:40

@LukasNys Мне кажется, хорошо, у вас включена миграция EF?

Dimitri 11.04.2019 15:56

@Dimitri, поскольку такой способ работы вызывает много проблем, я попробовал ваше второе решение, но с дополнительным полем «isEnd». Теперь я получаю следующую ошибку: gyazo.com/076f24c3f97ff1c0b4977010be59dc90. Любые подсказки относительно того, что вызывает это?

Lukas Nys 11.04.2019 16:14

@LukasNys Взгляните на первый ответ здесь => stackoverflow.com/questions/28531201/… P.S. Я бы постарался, чтобы первая попытка сработала, хотя :)

Dimitri 11.04.2019 16:19

Почему City Collection виртуальная?

Hamza Dahmoun 14.04.2020 15:54

@HamzaDahmoun: отложенная загрузка: любые виртуальные ICollections будут загружаться отложенно, если вы специально не пометите их иначе. (en.wikipedia.org/wiki/Lazy_loading)

Dimitri 16.04.2020 09:16

@Dimitri Спасибо за ответ

Hamza Dahmoun 16.04.2020 17:32

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