Когда я пытаюсь зарегистрировать пользователя на своем веб-сайте .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");
});
...
}
Я ожидаю, что это сработает (поскольку в моих глазах это отношение «один ко многим»), но это не так.
@Dimitri, спасибо за совет по соглашению об именах. Добавление аннотаций [Required] к StartCity и EndCity в Connection не решило проблему.





ОБНОВИТЬ
Здесь у вас есть несколько вариантов:
Вариант 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
Когда я пробую первый вариант, я получаю эту ошибку при построении: «Невозможно создать связь между« City.Connection »и« Connection.EndCity », потому что связь между« City.Connection »и« Conncection.StartCity » уже существует. . Свойства навигации могут участвовать только в одном отношении». Со вторым решением я теряю, какой город является отправной точкой, а какой — конечной. В этом случае важен их порядок.
Коллекция Города должна быть виртуальной.
Я согласен со вторым решением, неприменимым для вашего случая. Что касается ошибки, странно, не происходит на моей стороне. У вас включена миграция? Если это так, обновите свою модель. Если нет, можете ли вы показать мне, что у вас есть в onmodelcreating, и, в конце концов, как ваши классы выглядят сейчас?
@Dimitri Ошибка, которую я получаю: gyazo.com/6f6c006ca3d6979bc4134590e363435c. Класс Город (Стад): gyazo.com/7f1dae57a8c33ef2d3a19f7879a956eb. Соединение класса (связывание): gyazo.com/1a4a9a8485ccabd5fba81a8f98eaef77. OnModelCreating (часть City = Stad): gyazo.com/75434895014a3d355b5770b6710cc9ae. OnModelCreating (часть Connection = Verbinding): gyazo.com/16c7d3d8894bb906ab0f30afee61e1f5
@LukasNys Можете ли вы включить Entity ConnectionRoute (VerbindingRoute), пожалуйста?
Маршрут подключения класса @Dimitri (VerbindingRoute): gyazo.com/5946a8d704e1bd491f287527f09edf70. OnModelCreating (часть ConnectionRoute): gyazo.com/c0485f0e04174daeb3e268720382c6a6.
@LukasNys Мне кажется, хорошо, у вас включена миграция EF?
@Dimitri, поскольку такой способ работы вызывает много проблем, я попробовал ваше второе решение, но с дополнительным полем «isEnd». Теперь я получаю следующую ошибку: gyazo.com/076f24c3f97ff1c0b4977010be59dc90. Любые подсказки относительно того, что вызывает это?
@LukasNys Взгляните на первый ответ здесь => stackoverflow.com/questions/28531201/… P.S. Я бы постарался, чтобы первая попытка сработала, хотя :)
Почему City Collection виртуальная?
@HamzaDahmoun: отложенная загрузка: любые виртуальные ICollections будут загружаться отложенно, если вы специально не пометите их иначе. (en.wikipedia.org/wiki/Lazy_loading)
@Dimitri Спасибо за ответ
Вы также должны подумать о своем именовании, коллекции должны быть множественными (meervoud), например, ваши DbSets должны быть Connections & Cities, а также ваши свойства ConnectionStartCity и ConnectionEndCity. Что касается ошибки, это может быть связано с тем, что вам не хватает аннотации [Required] в вашем StartCity и EndCity.