#c# #entity-framework #asp.net-core
#c# #entity-framework #asp.net-core
Вопрос:
Когда я пытаюсь зарегистрировать пользователя на моем веб-сайте .NET Core 2.1 (используя identity) Я получаю следующую ошибку:
«Исключение InvalidOperationException: не удается определить связь, представленную свойством навигации «Город.ConnectionStartCity’ типа ‘ICollection’. Либо настройте связь вручную, либо проигнорируйте это свойство, используя атрибут ‘[NotMapped]’ или используя ‘EntityTypeBuilder.Игнорировать» в «OnModelCreating».».
Причина, по которой это происходит, вероятно, не имеет ничего общего с идентификацией, но регистрация и вход в систему в настоящее время — единственный известный мне способ ее запуска.
Мне все еще нужны свойства City
en ICollection<Connection>
в моих классах, поэтому я не хочу использовать [NotMapped]
атрибут.
Я поискал в Интернете и обнаружил, что это вызвано многими-многими отношениями, я чувствую, что это не тот случай, хотя.
Класс Connection
:
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; }
}
Класс City
:
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");
});
...
}
Я ожидаю, что это сработает (поскольку, на мой взгляд, это отношение «один ко многим»), но это не так.
Комментарии:
1. Вам также следует подумать о своем именовании, коллекции должны быть множественными (meervoud), например, вашими наборами баз данных должны быть Connections amp; Cities, а также ваши свойства ConnectionStartCity amp; ConnectionEndCity. Что касается ошибки, возможно, из-за того, что вам не хватает [Требуется] Аннотации к вашему StartCity amp; EndCity.
2. @Dimitri, спасибо за совет по соглашениям об именовании. Добавление [обязательных] аннотаций к StartCity и EndCity в Connection не решило проблему.
Ответ №1:
Обновить
Здесь у вас есть несколько вариантов:
Вариант 1 с результатом 1
Класс City становится:
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; }
}
Класс подключения становится:
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; }
}
Ваше OnModelCreating становится:
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 становится:
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; }
}
Класс подключения становится:
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.
Комментарии:
1. Я только что понял, что оставил некоторые слова непереведенными в своем вопросе. Это моя вина, извините! Я обновил ее, так что теперь это должно иметь больше смысла. Город — это просто таблица для городов (в моем случае Лондон, Брюссель, …), соединение должно быть соединением между двумя городами (например, «Лондон — Брюссель» или «Брюссель-Париж»). Итак, в City я хотел бы иметь список соединений, где город является начальной точкой, и список соединений, где город является конечной точкой. Полная модель базы данных (Stad = Город и Verbinding = Соединение): gyazo.com/8211bb2789e0f7a864aee1a6b9e21192
2. Когда я пробую первый вариант, я получаю эту ошибку во время сборки: «Не удается создать связь между ‘City. Соединение»и «Connection. EndCity», потому что уже существует связь между «Городом. Соединение»и «Conncection. StartCity». Свойства навигации могут участвовать только в одной связи.» Со вторым решением я теряю, какой город является отправной точкой, а какой — конечной. В этом случае важен их порядок.
3. Города коллекции должны быть виртуальными.
4. Я согласен со вторым решением, неприменимым для вашего случая. Что касается ошибки, странно, не происходит на моей стороне. У вас включена миграция? Если это так, обновите свою модель. Если нет, можете ли вы показать мне, что имеет ваш onmodelcreating и, в конечном итоге, как теперь выглядят ваши классы?
5. @Dimitri Спасибо за ваш ответ
Ответ №2:
В моем случае проблема возникла из-за переопределения OnModelCreating
в DbContext и не вызова base.OnModelCreating(builder)
.
Ответ №3:
Как и Шахзаиб, я исправил эту проблему для себя, вызвав base.OnModelCreating (builder) перед дополнительным кодом в переопределяющем методе
Комментарии:
1. Это должно быть опубликовано как комментарий, а не ответ
2. @Alberto Я согласен, но у меня недостаточно репутации, чтобы опубликовать комментарий, и все же хотел сообщить, что решение сработало