stackPusher
stackPusher

Reputation: 6512

Entity Framework doesn't generate navigation property despite having valid foreign key

I've seen similar questions but I don't see the connection between them and my issue and I think my problem is much simpler than those.

I'm using EF with a code-first approach which was working fine until I started adding explicit data annotations to my models (Required, and ForeignKey)

This may be an EF identity problem, or just a EF code-first problem

My model:

public class GroupMembership
{
    public int ID { get; set; }
    public int GroupID { get; set; }
    public string UserID { get; set; }

    [Required, ForeignKey("GroupID")]
    public virtual Group Group { get; set; }
    [Required, ForeignKey("UserID")]
    public virtual ApplicationUser User { get; set; }
}

Now the problem is when I try to add an instance:

GroupMembership grpMem = new GroupMembership()
{
    GroupID = grpID,
    UserID = userID,
};
context.GroupMemberships.Add(grpMem);
context.SaveChanges();

I get an error when trying to call SaveChanges(), and upon closer inspection I see that the ApplicationUser navigation property is null despite having a valid UserID. Meanwhile, the Group navigation property was successfully generated using GroupID.

UserID is the string ID associated with the current ApplicationUser, which I retrieve using

string userId = User.Identity.GetUserId();

Upvotes: 2

Views: 1235

Answers (2)

LiranBo
LiranBo

Reputation: 2136

try moving your required annotations to the fields instead of the navigation properties, like this:

public class GroupMembership
{
    public int ID { get; set; }
    [Required]
    public int GroupID { get; set; }
    [Required]
    public string UserID { get; set; }  
    [ForeignKey("GroupID")]
    public virtual Group Group { get; set; }
    [ForeignKey("UserID")]
    public virtual ApplicationUser User { get; set; }
}

To be honest I have no idea why the groupID thing worked, unless it is saved before you even edit it.

Notice that you got the error since the you didn't set the nav property in your code, you just set the foreign key values, this is also why you need to move the annotations.

Just as an alternative, I think that you can keep the Required annotation in case you also set it in your code before the savechanges().

Upvotes: 3

CodeNotFound
CodeNotFound

Reputation: 23220

I get an error when trying to call SaveChanges(), and upon closer inspection I see that the ApplicationUser navigation property is null despite having a valid UserID. Meanwhile, the Group navigation property was successfully generated using GroupID.

It's weird. Because all two properties are marked as virtual and if you enabled 'Lazy Loading' on your context then all navigational properties must be loaded on demand but it's not seem to be the case for User property.

Because your navigational properties have associated foreign key properties :

  • GroupID for Group
  • UserID for User

Then just put Required data annotation on them like the following code :

public class GroupMembership
{
    public int ID { get; set; }
    [Required]
    public int GroupID { get; set; }
    [Required]
    public string UserID { get; set; }

    [ForeignKey("GroupID")]
    public virtual Group Group { get; set; }
    [ForeignKey("UserID")]
    public virtual ApplicationUser User { get; set; }
}

Upvotes: 2

Related Questions