EntityFramework 4.0: InvalidOperationExeception: нарушение ограничения множественности

Недавно мы обновили наше программное обеспечение до .NET 4.0 и EF 4.0 (без объектов с самостоятельным отслеживанием) (ранее .NET 3.5 SP1). Теперь в прежнем рабочем коде возникает новое исключение, которое мы не понимаем.

У нас есть сущность под названием Resident и другая сущность под названием ResidentExtension, которая расширяет и без того большую сущность Resident отношением 1 к (0/1). Следующий код C# создает новую сущность в нашем приложении:

Residents resident = new Residents()
   {
       IsNewResident = true,
       ResidentImage = Settings.Default.ResidentCardDefaultMaleImage,
       IsActive = true,
       ResidentCanBeDeleted = true,
       ResidentExtensions = new ResidentExtensions(),
       ResidentMasterDataState = EvoState.Error,
       ResidentBasicDataState = EvoState.Error,
       ResidentBenefactorsDataState = EvoState.Error,
   };

Следующее исключение возникает непосредственно после этого оператора:

Нарушено ограничение множественности. Роль ResidentExtensions отношения VOCURA.EntityDataModels.EvocuraCarehomeManagementEntityModel.FK_ResidentExtensions_Residents имеет кратность 1 или 0..1.

Это происходит в сеттере сгенерированного кода:

    [XmlIgnoreAttribute()]
    [SoapIgnoreAttribute()]
    [DataMemberAttribute()]
    [EdmRelationshipNavigationPropertyAttribute("EVOCURA.EntityDataModels.EvocuraCarehomeManagementEntityModel", "FK_ResidentExtensions_Residents", "ResidentExtensions")]
    public ResidentExtensions ResidentExtensions
    {
        get
        {
            return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<ResidentExtensions>("EVOCURA.EntityDataModels.EvocuraCarehomeManagementEntityModel.FK_ResidentExtensions_Residents", "ResidentExtensions").Value;
        }
        set
        {
            ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<ResidentExtensions>("EVOCURA.EntityDataModels.EvocuraCarehomeManagementEntityModel.FK_ResidentExtensions_Residents", "ResidentExtensions").Value = value;
        }
    }

Единственное решение, которое я нашел, — сначала отправить объект Resident без расширения, а затем создать ResidentExtension с установкой внешнего ключа (ResidentID), добавить его в контекст и снова отправить. Но это не так, как это работало раньше.

Кто-нибудь знает, как заставить это работать по-старому?


person JanW    schedule 17.07.2010    source источник
comment
Ян, вы когда-нибудь решали эту проблему так, как хотели?   -  person John Kaster    schedule 22.03.2011
comment
К сожалению нет. Все еще использую решение, которое находится в последней части моего вопроса; (   -  person JanW    schedule 28.03.2011


Ответы (1)


ResidentExtensions = new ResidentExtensions(),

Я думаю, что эта линия вообще не нужна. Вы создаете новый объект residentextensions, который не имеет первичного ключа и не существует в базе данных. Когда контекст пытается сохранить резидентные расширения, это невозможно, так как свойство не установлено, что может привести к некоторым исключениям в базе данных, связанным с ненулевыми полями. Я думаю, что вам нужно сделать следующее;

Residents resident = new Residents()
   {
       IsNewResident = true,
       ResidentImage = Settings.Default.ResidentCardDefaultMaleImage,
       IsActive = true,
       ResidentCanBeDeleted = true,
       ResidentMasterDataState = EvoState.Error,
       ResidentBasicDataState = EvoState.Error,
       ResidentBenefactorsDataState = EvoState.Error,
   };
//Now you need to either initialize a residentextextensions entity
// with proper values, or just do not relate it with the resident entity.
ResidentExtensions temp = new ResidentExtensions();
temp.PropertyA = 3;
//etc.
resident.ResidentExtensions = temp;

Подводя итог, поскольку объект-резидент имеет отношение 1–0,1 к ResidentExtensions; если правая сторона равна 0; просто оставьте свойство ResidentExtensions нулевым; в противном случае инициализируйте правильный объект ResidentExtensions и установите соответствующее свойство.

person daryal    schedule 20.04.2012
comment
Насколько мне известно, в приведенном выше примере назначение объекта ResidentExtensions свойству навигации Residents автоматически устанавливает внешний ключ объекта ResidentExtensions в первичный ключ объекта Residents (именно так это работало в EF ‹ 4.0). Резидентный объект расширения правильно инициализирован, так как он содержит только внешний ключ (ResidentID) и свойства, допускающие значение NULL. P.S.: ResidentID является целым числом с автоматическим увеличением и, следовательно, не существует до отправки объекта с помощью SaveChanges. - person JanW; 17.07.2012