Entity Framework Core: связанные данные отсутствуют для каждого другого результата с SQLite - PullRequest
0 голосов
/ 22 октября 2018

У меня странная проблема при получении данных из базы данных.Это проект, который обновляется с .NET Core 1.0 до .NET Core 2.1.Все работало заранее, но обновление имеет некоторые странные побочные эффекты при загрузке связанных данных.Точные версии используются 2.1 для .NETCore.app;2.1.4 для AspNetCore, 2.1.4 для EntityFrameworkCore (.Sqlite).

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

public class Result
{
  public int Id { get; set; }
  public int MatchId { get; set; }
  public Match Match { get; set; }
}

public class Match
{
  public int Id { get; set; }
  public int? HomeId { get; set; }
  public int? AwayId { get; set; }
  public Result Home { get; set; }
  public Result Away { get; set; }
}

Что происходит, когда я получаю данные (например, context.Results.Include(r => r.Match)) и проверяю результаты, каждые другой результат пропускает связанные данные .Похоже, что это происходит только с этими таблицами, поэтому я предполагаю, что что-то сбивается из-за двунаправленности моделей.

Инспектор показывает результат, как показано ниже.Следует отметить, что наборы из двух последовательных результатов всегда указывают на один и тот же Match.

results - [0] Id = 1000 Match = Null - [1] Id = 1001 Match = <Match object> - [2] Id = 1002 Match = Null - [3] Id = 1003 Match = <Match object>

И так далее.У меня проблемы с вставкой данных в эти таблицы (всплывают похожие проблемы), но давайте пока не будем рассматривать этот вопрос.

1 Ответ

0 голосов
/ 22 октября 2018

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

Как примечание, эта проблема не имеет большого отношения к SQLite.Однако странным является то, что все работало так, как описано в вопросе.Я не смотрел на то, что вызвало это, но похоже, что либо Entity Framework двоичных файлов SQLite обрабатывал этот случай иначе.Не сказать, что это была ошибка, но то, что основное различие между версиями делает вероятным, что оно как минимум связано с этим.

Тем не менее, это решение.Изначально ModelBuilder имел следующие определения:

modelBuilder.Entity<Match>()
  .HasOne(m => m.Home)
  .WithMany()
  .HasForeignKey(m => m.HomeId);

modelBuilder.Entity<Match>()
  .HasOne(m => m.Away)
  .WithMany()
  .HasForeignKey(m => m.AwayId);

modelBuilder.Entity<Result>()
  .HasOne(r => r.Match)
  .WithOne()
  .HasForeignKey<Result>(r => r.MatchId);

Одна проблема с этим в том, что сопоставления WithMany из Match были неверными.Изменение этого значения на WithOne - хотя и более правильное - не имеет значения для проблемы.Это было исправлено удалением отображения отношений с Result на Match.По-видимому, это молчаливо отобразило обратную связь, выбрав одно из двух отношений к Result.Поскольку (я предполагаю) Entity Framework позаботится об обратном отношении, как только будет указан один конец, это можно (нужно) оставить, чтобы исправить вещи и сохранить все переходы.

Для полноты, окончательное определение ModelBuilder:

modelBuilder.Entity<Match>()
  .HasOne(m => m.Home)
  .WithOne()
  .HasForeignKey(m => m.HomeId);

modelBuilder.Entity<Match>()
  .HasOne(m => m.Away)
  .WithOne()
  .HasForeignKey(m => m.AwayId);
...