Junior
Junior

Reputation: 11990

Using Entity Framework, how can I add a foreign key on two models to reference each other

I have a ASP.NET MVC 5/C# project. In my project I have two models, Rule and MenuItem. MenuItem has a foreign key that references Rule. And Rule has a foreign key that references MenuItem.

Couple things worth mentioning, my model have a Prefix in the model name. Also, I am using database first approach.

I want to be able to get the MenuItem with the required rule using .Include(...) and also I want to be able to get the Rules with the MenuItem

Here are my models

[Table("Rules")]
public class PrefixRule
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string Id { get; set; }

    [ForeignKey("Item")]
    public int ModuleId { get; set; }
    public string Name { get; set; }

    public virtual PrefixMenuItem Item { get; set; }
}

[Table("MenuItems")]
public class PrefixMenuItem
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string Id { get; set; }

    [ForeignKey("RequiredRule")]
    public int? RequiredRuleId { get; set; }
    public string Name { get; set; }

    public virtual PrefixRule RequiredRule { get; set; }
}

However, when I try to pull the menu-items including the required-rule, I get the following error

One or more validation errors were detected during model generation:MenuItem_RequiredRule_Target: : Multiplicity is not valid in Role 'MenuItem_RequiredRule_Target' in relationship 'MenuItem_RequiredRule'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

I believe this error due to the circular references between my models. However, I need to be able to access both properties either way.

How can I fix this problem?

Upvotes: 5

Views: 2116

Answers (2)

Ppp
Ppp

Reputation: 1015

Entity Framework should be smart enough to figure out that this is 1 to 0/1 relationship. Not tested but this should work?

public partial class Rule
{
    [Key, ForeignKey("Item")]
    public string ModuleId { get; set; }
    public string Name { get; set; }

    public virtual MenuItem Item { get; set; }
}

public partial class MenuItem
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string Id { get; set; }

    public string Name { get; set; }

    public virtual Rule RequiredRule { get; set; }
}

Upvotes: 0

Travis Acton
Travis Acton

Reputation: 4440

If you are going this route then you have to make public string Id in the both the Primary and Foreign Key in your Rules table by decorating it with [Key, ForeignKey("PrefixMenuItem")]

See this article for a full example: http://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx

Updated Example:

public partial class Rule
{

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key, ForeignKey("Item")]
    public string Id { get; set; }

    [ForeignKey("Module")]
    public int ModuleId { get; set; }
    public string Name { get; set; }

    public virtual MenuItem Item { get; set; }
    public virtual Module Module { get; set; }
}

public partial class MenuItem
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string Id { get; set; }

    public string Name { get; set; }

    public virtual Rule RequiredRule { get; set; }
}

public partial class Module
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ModuleId { get; set; }

    public string Name { get; set; }

}

Upvotes: 0

Related Questions