Entity Framework Core пытается переустановить свойство навигации при сохранении после AddRange - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть следующая модель:

[Table("Facts")]
public partial class Facts
{
  [Key]
  public Guid ID { get; set; }
  public Guid UserID { get; set; }
  [ForeignKey(nameof(UserID))]
  public Users Users { get; set; }
  //other properties are ommitted
}

Код миграции:

migrationBuilder.CreateTable(
            name: "Facts",
            columns: table => new
            {
                ID = table.Column<Guid>(nullable: false),
                UserID = table.Column<Guid>(nullable: false),
            //other properties are ommitted
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Facts", x => x.ID);
                table.ForeignKey(
                    name: "FK_Facts_Users_UserID",
                    column: x => x.UserID,
                    principalTable: "Users",
                    principalColumn: "ID",
                    onDelete: ReferentialAction.Cascade);
            });

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

Это метод сохранения:

 public async Task SaveData<T>(List<T> data, bool isNew) where T : class
 {
   if (data == null)
      throw new ArgumentNullException(nameof(data));
   try
   {
     if (isNew)
       context.Set<T>().AddRange(data);
     else
     {
       context.Set<T>().AttachRange(data);
       data.ForEach(d => (context as DbContext).Entry(d).State = EntityState.Modified);
     }
     await context.SaveChangesAsync();
   }
   catch (Exception ex)
   {       
     throw;
   }
 }

Когда я вхожу в метод сохранения, у меня следующее состояние (идентификатор установлен, объект свойства навигации имеет значение null):

enter image description here

После AddRange у меня следующее состояние (идентификатор установлен, объект свойства навигации имеет значение , не ноль ):

enter image description here

Внутри улова я получаю следующее исключение:

Microsoft.EntityFrameworkCore.DbUpdateException: произошла ошибка при обновлении записей. Смотрите внутреннее исключение для деталей. ---> Microsoft.Data.Sqlite.SqliteException: ошибка SQLite 19: «ИНОСТРАННЫЙ КЛЮЧ» ограничение не выполнено '

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

Как я могу предотвратить повторную вставку уже существующего свойства навигации?

UPDATE

После включения ведения журнала SQL я получаю следующую информацию (@ p0 - это PK, @ p18 - это FK):

Failed executing DbCommand (105ms) [Parameters=[@p0='84ddca86-3f8a-41f1-aaed-2c65bd1cb384' (DbType = String),...@p18='e33f7939-bc35-4d82-b68b-e1cc0cf32ff1' (DbType = String)...]
INSERT INTO "Facts" ("ID", ... "UserID",...)
      VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18, @p19, @p20, @p21, @p22, @p23, @p24, @p25, @p26, @p27, @p28, @p29);
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 19: 'FOREIGN KEY constraint failed'.

UPDATE2

Я провел тестирование эмулятора и обнаружил следующее.

Данные таблицы Users изначально вставляются с помощью сценария SQL со следующим кодом:

public async virtual Task ExecuteCommandAsync(string sqlCommand)
{
  await context.Database.ExecuteSqlCommandAsync(new RawSqlString(sqlCommand));
}

Как видите, запись существует:

enter image description here

Когда я сохраняю несвязанные данные с помощью SaveData, его идентификатор сохраняется как двоичные данные :

enter image description here

Так, может быть, Entity Framework Core каким-то образом запутывается при попытке преобразовать двоичные данные в текст? До сих пор не знаю, почему извлечение работает нормально.

...