Entity Framework 6, проверка не работает должным образом

У меня есть следующий фрагмент кода

 var newPost = new Post()
                {
                    Activity = new Activity { Type = 1, ActivityTotalStatistic = new ActivityTotalStatistic() },
                    CreatedDate = oldPost.DateTimeCreated,
                    CategoryId = categoryId,
                    Title = oldPost.Name,
                    OwnerId = oldPost.UserID,
                    Slug = oldPost.Name,
                    LastUpdateDate = oldPost.DateTimeCreated,
                    PublishDate = oldPost.DateTimeCreated,
                    PostStatistic = new PostStatistic(),
                    PostItems = new List<PostItem>
                        {
                                new PostItem
                                {
                                    Activity = new Activity { Type = 2},<-- note this line of code
                                    CreatedDate = oldPost.DateTimeCreated,
                                    Title = oldPost.Name,
                                    Type = 1,
                                    Content = oldPost.Path
                                }
                            }

                    };

newDb.Posts.Add(newPost);
newDb.SaveChanges();

Это схема SQL для таблицы активности и статистики.

create table ActivityTotalStatistics
(
    Id int primary key identity(1,1),
    NumberOfLikes int not null,
    NumberOfDislikes int not null,
    SumOfLikes int not null,
    CommentCount int not null
)

create table Activities
(
    Id int identity (1,1) primary key,
    Type int not null,
    ActivityTotalStatisticId int not null  
        foreign key references ActivityTotalStatistics(Id)
)

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

Но EF его не распознает. Что происходит, так это то, что элемент сообщения получает ту же статистику активности из этой строки кода.

Activity = new Activity { Type = 1, ActivityTotalStatistic = new ActivityTotalStatistic() },

Является ли это допустимым поведением Entity Framework?

ОБНОВИТЬ Модель Activity.cs

public partial class Activity
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Activity()
        {
            this.ActivityLikes = new HashSet<ActivityLike>();
            this.Comments = new HashSet<Comment>();
            this.PostItems = new HashSet<PostItem>();
            this.Posts = new HashSet<Post>();
        }

        public int Id { get; set; }
        public int Type { get; set; }
        public int ActivityTotalStatisticId { get; set; }

        public virtual ActivityTotalStatistic ActivityTotalStatistic { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<ActivityLike> ActivityLikes { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Comment> Comments { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<PostItem> PostItems { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Post> Posts { get; set; }
    }

ActivityTotalStatistic.cs

public partial class ActivityTotalStatistic
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public ActivityTotalStatistic()
        {
            this.Activities = new HashSet<Activity>();
        }

        public int Id { get; set; }
        public int NumberOfLikes { get; set; }
        public int NumberOfDislikes { get; set; }
        public int SumOfLikes { get; set; }
        public int CommentCount { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Activity> Activities { get; set; }
    }

Можете ли вы опубликовать модель EF, связанную с вашей таблицей, и конфигурацию Entity, связанную с вашей моделью?

Derviş Kayımbaşıoğlu 18.02.2019 11:30

@simonare вам нужен XML или дизайнерский снимок экрана?

Robert 18.02.2019 11:35

@Robert Добавьте свой класс модели к вопросу.

TanvirArjel 18.02.2019 12:20

@TanvirAjel я добавил. это база данных в первую очередь

Robert 18.02.2019 13:01

Можете ли вы также поделиться классами Post и PostItem? Какова логическая иерархия ваших сущностей? Пост владеет активностью или активность владеет сообщениями? Я думал, что Post должен владеть Activity, но коллекция Posts и PostItems в Activity меня смутила. Принадлежит ли Activity пользователю, публикации или чему-то еще?

Mohammad 20.02.2019 17:16

@neptune Activity похож на базовую таблицу. У поста есть своя активность, у поста своя активность. Таким образом, я могу повторно использовать таблицу комментариев для ActivityComments вместо двух таблиц PostComments и PostItemComments.

Robert 20.02.2019 17:19

@Robert, вы уверены, что ActivityTotalStatistic, который добавляется в PostItem, принадлежит Post, а не новому? Я подозреваю, что EF создает для вас новую пустую статистику AcitivityTotalStatistic. Можете ли вы поделиться тем, что попадает в базу данных после выполнения кода, которым вы поделились?

Mohammad 20.02.2019 18:19

@neptune добавляет одно действие, устанавливает один и тот же идентификатор действия для публикации и публикации. Если я не создам экземпляр в сообщении, он выдает исключение

Robert 20.02.2019 18:23

Я думаю, что EF предполагает неправильное направление отношений. Он может рассматривать Activity как родитель, а Post и PostItem как его дочерние элементы. Я знаю, что это не объясняет, почему Activity повторно используется как в Post, так и в PostItem, которые вы создаете, но я думаю, что EF обычно не ожидает такого указания отношений. См. здесь в разделе Условные обозначения: docs.microsoft.com/en-us/ef/core/modeling/… Как выглядят таблицы Post и PostItem?

Mohammad 20.02.2019 18:58
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
9
303
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Is this a valid behavior of Entity Framework?

Я так не думаю - к сожалению, нет официальной документации/спецификации для этих режимов отслеживания, но похоже на побочный эффект/дефект реализации (ошибка).

Обоснование:

Это происходит Только, когда средство отслеживания изменений содержит не замужемAdded основной объект с автоматически сгенерированным PK, зависимый объект имеет как свойство явной ссылки навигации, так и свойство FK, все со значениями по умолчанию («0» и null).

Это нет происходит, если:

(1) Существует второй Added основной объект:

newDb.Set<ActivityTotalStatistic>().Add(new ActivityTotalStatistic());

SaveChanges бросает DbUpdateException:

Unable to determine the principal end of the 'Activity_ActivityTotalStatistic' relationship. Multiple added entities may have the same primary key.

Не очень удобный, но все же исключение.

(2) Зависимый объект не имеет явного свойства FK, но правильно сконфигурировал требуемое теневое свойство FK. SaveChanges бросает:

Entities in 'MyDbContext.Activities' participate in the 'Activity_ActivityTotalStatistic' relationship. 0 related 'Activity_ActivityTotalStatistic_Target' were found. 1 'Activity_ActivityTotalStatistic_Target' is expected.

Опять же, не очень удобно, но все же исключение.

(3) К свойству ссылочной навигации применен атрибут [Required]:

[Required]
public virtual ActivityTotalStatistic ActivityTotalStatistic { get; set; }

SaveChanges бросает ValidationException, содержащий ValidationError с (наконец-то) удобным для пользователя сообщением:

The ActivityTotalStatistic field is required.


Вернемся к исходному делу. Только и только в этом конкретном случае EF находит единственный ожидающий экземпляр основного объекта Added и связывает его со всеми ожидающими зависимыми объектами, имеющими ActivityTotalStatistic == null и ActivityTotalStatisticId == 0.

Все это для меня указывает на баг/непреднамеренное поведение EF6. Кажется, что лучший способ предотвратить это — украсить необходимые справочные свойства навигации атрибутом [Required], но это проблематично в сгенерированной модели объекта Database First (edmx), такой как ваша.

Тогда мы будем называть это ошибкой или нежелательным поведением.

Robert 22.02.2019 14:59

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