EF6 AutoMapper6 Различное поведение родителей / детей - PullRequest
0 голосов
/ 10 октября 2018

Я только что обновил все приложение WCF с EF4 / AutoMapper 1.1 до EF6 / AutoMapper 6.0.0.2 , и поведение не совсем то же самое.

Этоне работает для меня: Entity Framework - Добавить дочернюю сущность

До :

child.Parent = parentObject

ИЛИ

parentObject.Children.Add(child)

имел тот же результат в режиме реального времени (при отладке == до SaveChanges), поэтому я решил использовать child.Parent = parentObject для удобства чтения.child.Parent = parentObject автоматически добавляет дочерний элемент в parentObject.Дочерний объект также был добавлен в БД.

Теперь : child.Parent = parentObject больше не достаточно (дочерний элемент не добавлен в БД), я должен добавить parentObject.Children.Add (ребенок).Иногда мне нужна ссылка child.Parent = parentObject, поэтому я должен написать обе строки.Может кто-нибудь объяснить мне, почему он больше не работает?

Также: я мог бы написать до :

Mapper.CreateMap< Patient, PATIENTENTITY >()
                .ForMember(dest => dest.Gender, opt => opt.ResolveUsing< PatientGenderResolver >())
                .ForMember(dest => dest.REF_GENDER, opt => opt.Ignore())

, где dest.Gender - PK (int)и PatientGenderResolver найти идентификатор (int) пола в таблице REF_GENDER.Этого сопоставления было достаточно, чтобы установить PATIENTENTITY.REF_GENDER в реальном времени благодаря распознавателю Id.

Теперь идентификатор установлен, но PATIENTENTITY.REF_GENDER остается нулевым.Также я попытался установить непосредственно PATIENTENTITY.REF_GENDER с помощью распознавателя, но он добавил пол в таблицу REF_GENDER ...

Итак, еще раз, может кто-нибудь объяснить мне, почему он больше не работает?

РЕДАКТИРОВАТЬ Некоторые точности: До:

    patientEntity = Mapper.PatientToEntity(patientModel);
    //patientEntity.REF_GENDER is null
    Context.PATIENTENTITIES.AddObject(patientEntity);
    //patientEntity.REF_GENDER is set !
    Context.SaveChanges();

Сейчас:

patientEntity = Mapper.PatientToEntity(patientModel);
//patientEntity.REF_GENDER is null
Context.PATIENTS.Add(patientEntity);
//patientEntity.REF_GENDER is still null !
//patientEntity.REF_GENDER = Context.REF_GENDER.Find(patientEntity.Gender);//I am obliged to add this line everywhere for every REF !
Context.SaveChanges();

Я предполагаю, чтодве проблемы у меня связаны

РЕДАКТИРОВАТЬ Я просто возвращаюсь в свой проект.Теперь у меня есть EF6 и Automapper 1.1.Проблемы точно такие же, поэтому, я думаю, Automapper не задействован.

EDIT Я обхожу проблему REF_GENDER с

patientEntity = Mapper.PatientToEntity(patientModel, Context);
public PATIENT PatientToEntity(Patient patient, EntityContainer context)
{
    PATIENT entity = AutoMapper.Mapper.Map<Patient, PATIENT>(patient);
    if (patient.Id == null || patient.Id == Guid.Empty)
        entity.PatientId = Guid.NewGuid();
    else
        entity.PatientId = patient.Id;

    entity.REF_GENDER = context.REF_GENDER.Find(entity.Gender);

    return entity;
}

Очевидно, контекст должен бытьто же самое, новый REF_GENDER добавляется в db

1 Ответ

0 голосов
/ 14 октября 2018

Вы не упоминаете это явно, но вы не только перешли с EF 4 на 6, но и с ObjectContext на DbContext.Это огромная разница в поведении классов сущностей.

В ObjectContext API сгенерированные классы сущностей были заполнены кодом, тесно взаимодействующим с контекстом, в котором они были задействованы. Ссылочное свойство, такое как child.Parent, будетвыглядит так:

public Parent Parent
{
    get
    {
        return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Parent>("model.FK_Child_Parent", "Parent").Value;
    }
    set
    {
        ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Parent>("model.FK_Child_Parent", "Parent").Value = value;
    }
}

Таким образом, установка этого свойства устанавливает свойство Value для EntityReference<Parent>.Код EF4.1 не является общедоступным, поэтому мы можем только догадываться, что происходит внутри.Ясно одно: он меняет состояние child на Added - если child еще не был присоединен к контексту.

К счастью, EF отказалась от этой жесткой блокировки поставщика, когда выпустилаDbContext API (в EF 4.1 не менее).Теперь это сгенерированное свойство - не что иное, как авто-свойство:

public Parent Parent { get; set; }

Это значительно упростило объединение режимов работы с EF на основе базы данных и на уровне кода.На самом деле классы сущности как с кодом, так и с базой данных были теперь POCO.

Цена (если хотите) заключается в том, что EF не может следить за всем, что происходит раньше, настолько близко, насколько это возможно. До все классы сущностей, унаследованные от EntityObject, и EF могли отслеживать все их взаимодействия.Утверждение ...

child.Parent = parentObject;

втянет еще неизвестный child в контекст через присоединенный parentObject.

Now , когда кто-то устанавливает child.Parent, никто, кроме child, не знает, что случилось, даже Parent.Это означает, что 1039 * вообще не сможет EF узнать об этом изменении, когда его трекер изменений выполнит DetectChanges (как это происходит очень часто).

Вот почему с использованием DbContextВы должны добавить нового дочернего элемента в контекст самостоятельно, либо явно указав его состояние, либо добавив его в context.Children.Или добавив его в parent.Children, что является изменением, которое отслеживатель изменений может обнаружить, если parent подключено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...