5

We have recently upgraded our software to .NET 4.0 and EF 4.0 (without self-tracking entities) (former .NET 3.5 SP1). Now a new exception is raised in former working code, which we do not understand.

We have an entity called Resident, and another entity called ResidentExtension, which extends the already large Resident entity with a 1 to (0/1) relationship. The following c# code generates a new entity in our application:

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,
   };

The following exception is directly raised after this statement:

Multiplicity constraint violated. The role 'ResidentExtensions' of the relationship VOCURA.EntityDataModels.EvocuraCarehomeManagementEntityModel.FK_ResidentExtensions_Residents' has multiplicity 1 or 0..1.

It occurs in the setter of the generated code:

    [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;
        }
    }

The only solution I have found yet is to submit the Resident entity without extension first, and after this, creating a ResidentExtension with setting the foreign key (ResidentID) and adding it to context and submit again. But this is not the way it worked before.

Does anyone know the how to make this work the old way again?

Eric J.
  • 147,927
  • 63
  • 340
  • 553
JanW
  • 1,799
  • 13
  • 23

1 Answers1

1
ResidentExtensions = new ResidentExtensions(),

I think this line is not needed at all. You are creating a new residentextensions object which does not have any primary key and which does not exist in the database. When context tries to save the residentextensions, it can't since no property is set, possibly leading to some exceptions in the database related to non-nullable fields. I think what you need to do is the following;

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;

As a summary, since Resident entity has 1 - 0,1 relation with ResidentExtensions; if the right side is 0; just leave the ResidentExtensions property null; otherwise initialize a proper ResidentExtensions object and set the related property.

daryal
  • 14,643
  • 4
  • 38
  • 54
  • As far as I know, in the matter of the above example, assigning the ResidentExtensions object to the Residents navigation property automatically sets the foreign key on the ResidentExtensions object to the primary key of the Residents object (that is the way it worked in EF < 4.0). The resident extension object ist properly initialized, since it only contains the foreign key (ResidentID) and nullable properties. P.S.: ResidentID is integer with auto increment and therefore not existant before submitting the entity with SaveChanges. – JanW Jul 17 '12 at 11:44