Невозможно обновить или удалить в локальной базе данных: ошибка

Я новичок в С# и .NET, я пытаюсь реализовать функциональность CRUD с локальной базой данных. Поэтому я создал класс Product, который содержит атрибуты и внешние ключи. Но я получаю сообщение об ошибке при запуске приложения. Методы Update() и Delete() не работают, а метод Add() работает нормально.

Вот мои общие методы -

public class GenericRepository<T> where T : class
{    
    GPContext context;
    IDbSet<T> dbSet;    

    public GenericRepository()
    {
        context = new GPContext();
        dbSet = context.Set<T>();
    }    

    public IEnumerable<T> getAll()
    {
        return dbSet.AsEnumerable();                
    }    

    public T GetById(int id)
    {
        return dbSet.Find(id);
    }    

    public void Add(T t)
    {
        dbSet.Add(t);
        context.SaveChanges();
    }    

    public void Update(T t)
    {
        dbSet.Attach(t);
        //on modifie la instance avant la inserer dans la bd
        context.Entry(t).State = EntityState.Modified;
        context.SaveChanges();
    }    

    public void Delete(T t)
    {
        dbSet.Remove(t);
        context.SaveChanges();
    }    
}

а вот как я их называю Program.cs -

GenericRepository<Product> productRepository = new GenericRepository<Product>();
           
Address adresse = new Address() { City = "Paris", StreetAdress = "Escalier 9" };
Category cat1 = new Category() {  Name = "cat1"   };

Chemical p1 = new Chemical() { ProductId=26,  DateProd = DateTime.Now , myAdress = adresse, Description = "CHemichal Product",
    Price = 55,Name = "PHARMA CHEMICH 1", Quantity = 100 , MyCategory = cat1};
Chemical p2 = new Chemical() {ProductId = 12 , DateProd = DateTime.Now , myAdress = adresse, Description = "CHemichal Update Product",
    Price = 55,Name = "PHARMA CHEMICH 1 Update", Quantity = 100 , MyCategory = cat1};
Product p3 = new Product() { ProductId = 11 };

productRepository.Add(p1);
productRepository.Update(p2);
productRepository.Delete(p3);   

При запуске приложения возникает следующая ошибка -

System.InvalidOperationException : 'Ограничение ссылочной целостности Произошло нарушение: значение свойства "Category.CategoryId" на один конец отношения не соответствует значению(ям) свойства «Product.categoryId» на другом конце».

Также у меня есть эта ошибка в методе Delete -

System.InvalidOperationException : 'Объект не может быть удален потому что он не был найден в ObjectStateManager.

Классы сущностей ниже -

Product:

public class Product : Concept
{
    [Display(Name  = "Date de prod")]
    [DataType(DataType.Date)]
    public DateTime DateProd { get; set; }
    
    [DataType(DataType.MultilineText)]
    public string Description { get; set; }
    
    [Required(ErrorMessage  = "Champ obligatoire")]
    [StringLength(25)]
    [MaxLength(50 , ErrorMessage  = "taille max dans la base 50")]
    public string Name { get; set; }
    
    [DataType(DataType.Currency)]
    public double Price { get; set; }
    
    public int ProductId { get; set; }
    
    [Range(0,int.MaxValue)]
    public int Quantity { get; set; }
    
    [DataType(DataType.ImageUrl) ,Display(Name  = "Image")]
    public string image { get; set; }

    [ForeignKey("categoryId")]
    public  Category MyCategory { get; set; }
    
    public int? categoryId { get; set; }
    
    public List<Provider> Providers { get; set; }

    public override void GetDetails()
    {
        Console.WriteLine("Product  Name:, Price   "+ Name + " " + Price);    
    }

    public virtual void GetMyType()
    {
        Console.WriteLine("Uknown");
    }    
}

Chemical:

public class Chemical : Product
{
   // public string City { get; set; }
   
    public string LastName { get; set; }
    
   // public string StreetAddress { get; set; }
   
    public Address myAdress { get; set; }
    
    public override void GetMyType()
    {
        System.Console.WriteLine("CHEMICAL");
    }
}

Biological:

public class Biological : Product
{
    public string Herbs { get; set; }

    public override void GetMyType()
    {
        Console.WriteLine("Biological");
    }
}

Я действительно новичок, и я понятия не имею о том, что я должен сделать или изменить. Я прочитал другие ответы на ту же тему, и я не понял, что делать.

Можете ли вы также опубликовать свои классы Entity: Category, Chemical и Product? Кроме того, вы пытаетесь добавить и обновить «Химический» через репозиторий, введенный для «Продукта».

Neil W 20.12.2020 00:48

Типы значений в базе данных не совпадают с вашим определением класса. В Entity есть файл сопоставления EDMX, который используется для сопоставления классов С# с полями базы данных. Один или несколько не совпадают.

jdweng 20.12.2020 00:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
108
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Во-первых, вы создаете 3 новых объекта и пытаетесь добавить, обновить и удалить их. Новую сущность можно добавить, но нельзя обновить или удалить. Подумайте об этом, это объект, который вы только что создали, и его еще нет в базе данных. Как вы ожидаете обновить/удалить его? Чтобы обновить или удалить объект, он должен быть существующим.

Во-вторых, вы используете вновь созданные (без идентификатора) объекты Address и Category для обновления свойств myAdress и MyCategory. Эти два свойства не являются примитивными свойствами, представляющими значения столбцов, как остальные, они являются связанными объектами с ограничениями внешнего ключа. Если вы действительно хотите изменить/обновить их, вы должны установить тот, который уже существует в базе данных с идентификатором. В противном случае это нарушит ограничение внешнего ключа (или ограничение ссылочной целостности), именно об этом говорится в первом сообщении об ошибке.

Попробуйте следующее, для обновления -

// retrieve an existing address from database
Address newAddress =  new GenericRepository<Address>().GetById(3);

// retrieve an existing category from database
Category newCategory = new GenericRepository<Category>().GetById(5);

// retrieve an existing product from database
Chemical p2 =  new GenericRepository<Product>().GetById(12);

// update/change properties, but don't change the ProductId
p2.DateProd = DateTime.Now;
p2.myAdress = newAddress;
p2.Description = "CHemichal Update Product";
p2.Price = 55;
p2.Name = "PHARMA CHEMICH 1 Update";
p2.Quantity = 100;
p2.MyCategory = newCategory;

// now call for update
productRepository.Update(p2);

и для Удалить -

// retrieve an existing product from database
Product p3 = productRepository.GetById(11);

// now call for delete
productRepository.Delete(p3);

Другие вопросы по теме