Как сначала определить отношения «многие ко многим» и «один ко многим» между двумя объектами в коде?

Я создаю веб-сайт, используя сначала код entity-framework, где: пользователь может продавать много товаров: один-ко-многим. пользователь может покупать много продуктов, а продукты могут покупать многие пользователи: многие ко многим. я получаю сообщение об ошибке:

System.Data.SqlClient.SqlException: 'Introducing FOREIGN KEY constraint 'FK_dbo.UserProducts_dbo.Products_Product_ProductId' on table 'UserProducts' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

Я действительно хочу каскадное удаление, чтобы удалить продукты, принадлежащие пользователю, который удалил свою учетную запись, или удалить записи из таблицы UserProduct, принадлежащие удаленному пользователю, или удаленный продукт. Что я делаю неправильно?

это класс User:

public class User
{
    public int UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDate { get; set; }
    public string Email { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }


    public ICollection<Product> Products { get; set; }
    [InverseProperty("Users")]
    public ICollection<Product> Cart { get; set; }

    public User()
    {
        Products = new List<Product>();
        Cart = new List<Product>();
    }
}

это класс продукта:

public class Product
{
    [Key]
    public int ProductId { get; set; }
    public int OwnerId { get; set; }
    public string Title { get; set; }
    public string ShortDescription { get; set; }
    public string LongDescription { get; set; }

    public byte[] Picture1 { get; set; }
    public byte[] Picture2 { get; set; }
    public byte[] Picture3 { get; set; }

    [ForeignKey("OwnerId")]
    public User User { get; set; }
    public ICollection<User> Users { get; set; }

    public Product()
    {
        Users = new List<User>();
    }
}

nvm я говорю, но название ошеломило меня на мгновение лол

Christopher H. 06.04.2018 17:32

Вы добавили ссылку на внешний ключ в построитель модели?

j9070749 06.04.2018 17:38

@ j9070749 добавить к каким? коллекциям: ef frame-work делает это по соглашению, когда 2 объекта имеют коллекцию друг друга. а для «один ко многим» я использовал аннотацию внешнего ключа в модели продукта, которая должна выполнять эту работу.

Itay Tur 06.04.2018 19:33

Исключение ясно говорит вам, что происходит. Вы должны выбрать один внешний ключ, который может выполнять каскадное удаление. Используйте плавные сопоставления, чтобы отключить каскадное удаление на других FK.

Gert Arnold 06.04.2018 22:41

Исключение, говорящее о недопустимом ограничении между таблицей UserProducts и Product. но почему. если ef-framework создает таблицу UserProducts, принципами являются продукт и пользователь. удаление записи из UserProducts не должно влиять ни на таблицу продуктов, ни на пользователя. но удаление продукта или записи пользователя должно. где недопустимый каскад?. @ GertArnold

Itay Tur 07.04.2018 01:33

@UNlessofficialchannel Когда вы удаляете User, UserProduct можно удалить с помощью (1) User -> UserProduct или (2) User -> Product -> UserProduct, следовательно, несколько каскадных путей.

Ivan Stoev 07.04.2018 20:53

@IvanStoev вот как я хочу, чтобы это работало. Что делать, чтобы эф его примет?

Itay Tur 08.04.2018 11:13

@UNlessofficialchannel Что ж, то, что вы хотите, не всегда то, что вы получаете может. К сожалению, это ограничение EF (происходит из-за ограничения базы данных SqlServer), поэтому вы ничего не можете сделать, чтобы позволить EF «принять это». Все, что вы можете сделать, это подписаться на комментарий Герта Арнольда.

Ivan Stoev 08.04.2018 11:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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
8
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Сначала мне нужно было написать класс для средней таблицы в отношении «многие-ко-многим», «пользователи-продукты»:

public class UserProduct
{
    [Key, Column(Order = 0), ForeignKey("User")]
    public int UserId { get; set; }
    [Key, Column(Order = 1), ForeignKey("Product")]
    public int ProductId { get; set; }

    public User User { get; set; }
    public Product Product { get; set; }
}

которые позволяют мне отключить каскад при удалении из этой таблицы в таблицу User (переопределив OnModelCreating в классе контекста):

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<UserProduct>().HasRequired(t => 
        t.User).WithMany(t => t.Cart).WillCascadeOnDelete(false);
    }

отключение каскада работает, потому что:

  1. он решает ошибку множественного каскадного пути.
  2. удаление пользователя по-прежнему удаляет его продукты и их пользовательские продукты, и удаление продукта приведет к удалению его UserProducts.

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