Alex
Alex

Reputation: 1947

Multiplicity constraint violation EF Code-First

i've a problem with using Entity-Framework 6. I've two classes

public class LinkableState : Entity
{
    [Required]
    public long LinkableId { get; set; }
    [ForeignKey(@"LinkableId")]
    public virtual Linkable Linkable { get; set; }
    public long Counter { get; set; }
    public string Debug { get; set; }
}

and

public class ProcessInstance : InstanceBase<Process>
{
    [Required]
    public DateTime InstanceStartTime { get; set; }        
    public DateTime? InstanceEndTime { get; set; }        
    public ProcessInstanceState InstanceEndState { get; set; } = ProcessInstanceState.None;
    public virtual ICollection<LinkableState> LinkableStates { get; set; } = new List<LinkableState>();
    public virtual ICollection<LinkableState> LinkableStateTopCounter { get; set; } = new List<LinkableState>(); 
}

Within my code i like to change ProcessInstance.LinkableStates like in this example (at this time the elements of reachedStates are detached)

using (IDataLayer db = StorageFactory.GetStore())
{
     ProcessInstance ix = db.GetProcessInstance(processInstanceId);
     ix.LinkableStates = reachedStates;
}

if the db obejct get's disposed and saved i get the error

Multiplicity constraint violated. The role 'ProcessInstance_LinkableStates_Source' of the relationship 'DataLayer.Mssql.DataBase.ProcessInstance_LinkableStates' has multiplicity 1 or 0..1.

I don't know why EF thinks that there is more than 1 relation ? I've checked the EDMX file (reverse from Code-First) which looks like this:

Reverse EDMX Db-Entries

As you can see in the db-entries the key of ProcessInstance_Id (ProcessInstance.LinkableStates) has been nulled even if ID {1, 3} should be set with Process.Id = 1.

This error occured while i switched from

Configuration.ProxyCreationEnabled = true;
Configuration.LazyLoadingEnabled = true;

to

Configuration.ProxyCreationEnabled = false;
Configuration.LazyLoadingEnabled = false;

At the Moment i've absolute no idea why this error occurs when i switch from lazy to eager loading. i already tried to clear the list and add the new elements manually like:

using (IDataLayer db = StorageFactory.GetStore())
{
    ProcessInstance ix = db.GetProcessInstance(processInstanceId);
    ix.LinkableStates.Clear();
    foreach (LinkableState e in unvisitedStates)
    {
        ix.LinkableStates.Add(e);
    }
}

but this does not change anything.

Do you have any ideas how i can fix this problem ?

thanks in advance :)

Upvotes: 0

Views: 676

Answers (1)

Alex
Alex

Reputation: 1947

Okay, seems like I've solved the Problem.

I did two things. First, i've added the InverseProperty Annotation to my classes

public class LinkableState : Entity
{
    ...   
    public long? LinkableStatesId { get; set; }
    public long? LinkableStateTopCounterId { get; set; }
    [InverseProperty(@"LinkableStates")]
    [ForeignKey(@"LinkableStatesId")]
    public virtual ProcessInstance ProcessInstanceLinkableStates { get; set; }
    [InverseProperty(@"LinkableStateTopCounter")]
    [ForeignKey(@"LinkableStateTopCounterId")]
    public virtual ProcessInstance ProcessInstanceLinkableStateTopCounter { get; set; }
}

public class ProcessInstance : InstanceBase<Process>
{
    ...
    [InverseProperty(@"ProcessInstanceLinkableStates")]
    public virtual ICollection<LinkableState> LinkableStates { get; set; } = new List<LinkableState>();

    [InverseProperty(@"ProcessInstanceLinkableStateTopCounter")]
    public virtual ICollection<LinkableState> LinkableStateTopCounter { get; set; } = new List<LinkableState>(); 
}

and the second thing is that i set the reference Id for LinkableStates by Hand before i save them and check for a already stored version first.

foreach (LinkableState e in copy)
{
    LinkableState tmp = db.GetLinkableState(e.Id) ?? e;
    tmp.LinkableStatesId = ix.Id;
    ix.LinkableStates.Add(tmp);
}

for now this solved my "Multiplicity constraint violation" error. Hope this will help someone else faceing this problem.

Upvotes: 2

Related Questions