0

Я использую сущность framework 7 (core) и базу данных Sqlite. В настоящее время с помощью COMBOBOX изменить категорию сущности этого метода:Entity framework parent -> дочерняя привязка и ошибка внешнего ключа сбой Ошибка

/// <summary> 
/// Changes the given device gategory. 
/// </summary> 
/// <param name="device"></param> 
/// <param name="category"></param> 
public bool ChangeCategory(Device device, Category category) 
{ 
    if (device != null && category != null) 
    { 
     try 
     { 
      var selectedCategory = FxContext.Categories.SingleOrDefault(s => s.Name == category.Name); 
      if (selectedCategory == null) return false; 
      if (device.Category1 == selectedCategory) return true; 

      device.Category1 = selectedCategory; 
      device.Category = selectedCategory.Name; 
      device.TimeCreated = DateTime.Now; 
      return true; 
     } 
     catch (Exception ex) 
     { 
      throw new InvalidOperationException("Category change for device failed. Possible reason: database has multiple categories with same name."); 
     } 
    } 
    return false; 
} 

Эта функция изменяет идентификатор категории для device просто отлично. Но верно ли это?

После связывания и затем позже во время удаления этого category я получаю сообщение об ошибке из Sqlite базы данных:

{ "SQLite Ошибка 19: 'Ограничение внешнего ключа не удалось'"}

удаления категории метод

public bool RemoveCategory(Category category) 
{ 
    if (category == null) return false; 
    var itemForDeletion = FxContext.Categories 
     .Where(d => d.CategoryId == category.CategoryId); 
    FxContext.Categories.RemoveRange(itemForDeletion); 
    return true; 
} 

EDIT Вот структуры device и category:

CREATE TABLE "Category" (
    "CategoryId" INTEGER NOT NULL CONSTRAINT "PK_Category" PRIMARY KEY AUTOINCREMENT, 
    "Description" TEXT, 
    "HasErrors" INTEGER NOT NULL, 
    "IsValid" INTEGER NOT NULL, 
    "Name" TEXT 
) 

CREATE TABLE "Device" (
    "DeviceId" INTEGER NOT NULL CONSTRAINT "PK_Device" PRIMARY KEY AUTOINCREMENT, 
    "Category" TEXT, 
    "Category1CategoryId" INTEGER, 
    CONSTRAINT "FK_Device_Category_Category1CategoryId" FOREIGN KEY ("Category1CategoryId") REFERENCES "Category" ("CategoryId") ON DELETE RESTRICT, 
) 

ответ

1

Ваш SQLite таблица имеет внешний ключ ограничения ON DELETE RESTRICT. Это означает, что если какая-либо строка в Устройствах по-прежнему указывает на категорию, которую вы пытаетесь удалить, база данных SQLite предотвратит эту операцию. Чтобы обойти это, вы можете (1) явно изменить все Устройства на другую категорию или (2) изменить поведение ON DELETE на что-то другое, например CASCADE или SET NULL. См. https://www.sqlite.org/foreignkeys.html#fk_actions

Если вы использовали EF для создания своих таблиц, то настройте свою модель на использование по-другому. По умолчанию используется ограничение. См. https://docs.efproject.net/en/latest/modeling/relationships.html#id2. Пример:

 modelBuilder.Entity<Post>() 
      .HasOne(p => p.Blog) 
      .WithMany(b => b.Posts) 
      .OnDelete(DeleteBehavior.Cascade); 
+0

Aa да, в основном эта ошибка желательна. Однако в некоторых случаях это исключение не всегда происходит, а база данных позволяет удалить категорию, в которой указывают некоторые устройства. Например, когда я запустил приложение и удалил одну категорию, но если во время выполнения я изменяю поле категории устройств и затем пытаюсь удалить его, это исключение происходит. – ajr

+0

Возможно, у вас есть хороший источник/учебник для чтения о правильных способах обработки исключений сущности framework 'SaveChanges()' method? – ajr