1

I am creating a system that requires a user to approve actions in an application. One of the actions is adding a user the work flow is as follows.

  1. An existing user adds a new user.
  2. This action creates a row in the user table and a row in the linked approval table.
  3. When the user logs in if they have not been approved it will be rejected.

The problem is I get the following error

ApplicationUser_Approval_Source: : Multiplicity is not valid in Role 'ApplicationUser_Approval_Source' in relationship 'ApplicationUser_Approval'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

This seems to be due to a circular foreign key my classes are as follows:

public class Approval
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public bool IsApproved { get; set; }

    public virtual IApprovalAction Action { get; protected set; }

    public virtual ApplicationUser RequestingUser { get; set; }

}

public class ApplicationUser : IdentityUser<string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim>, IUser, IUser<string>, IApprovalAction
{
    [ForeignKey("Approval")]
    public int ApprovalId { get; set; }

    public virtual Approval Approval { get; set; }
}

Any help would be awesome.

Rajdeep Dosanjh
  • 1,157
  • 1
  • 9
  • 20

1 Answers1

2

The problem is that you are trying to create a one-to-one relationship, but, in this kind of relationship, Entity Framework requires that the primary key of the dependent also be the foreign key.So, don't map ApprovalId as FK, otherwise, EF requires that FK must be PK too (comment that property).

The other problem is going to happen is EF doesn't know who is the principal end in your relationship. To especify who is the principal, use the Required attribute. If you, for example, add this attribute over the Approval property, you are specifying that to create a ApplicationUser, the Aproval property must be set it after save changes, so your principal in this case is Aproval and the dependend is ApplicationUser.

I suggest you check this links:

Update

Well, if you want to create a one-to-one relationship that are optional in both side, you could do this using Fluent Api:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   modelBuilder.Entity<ApplicationUser>()
               .HasOptional(au => au.Aproval)
               .WithOptionalPrincipal(a => a.RequestingUser);
}
Community
  • 1
  • 1
ocuenca
  • 38,548
  • 11
  • 89
  • 102
  • Agree, but `ApplicationUser` is the only possible principal here, because they can exist without `Approval`. – Gert Arnold Feb 13 '15 at 21:36
  • Yeah the problem is with linking in this way is that it links application user to the existing user this is not what i want to achieve. – Rajdeep Dosanjh Feb 14 '15 at 14:37
  • Hello @RajdeepDosanjh, I have uptaded mi answer. You can try with this new relationship configuration, hope that helps you. – ocuenca Feb 14 '15 at 15:14