2

I'm using Entity Framework 4.3 and doing code first. I have two tables that are in a 1 to 0 or 1 relationship like such...

class User
{
    [key]
    public int UserID {get; set;}
    // other props
}

class UserStats
{
    [key]
    public int UserID {get; set;}
    // other props


    public virtual User User {get; set;}
}

I'm also using ASP.Net WebAPI 2.2 w/ OData v4 and the OData Client Code Generator template.

The metadata file that WebAPI creates is missing the IsNullable="False" attribute on the User's UserID property. So the OData Client Code Generator is making the User class's UserID property nullable, which is not true, especially with it being the primary key.

I've tried adding [Required] to the User property on UserStats, however then any updates will throw a validation exception if I don't include a User when saving/updating the UserStats class.

I feel like I'm missing something.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
MHollis
  • 1,449
  • 9
  • 23

1 Answers1

1

In an one to one relationship one end must be the principal and the another one is the dependent. EF requires that the PK of the dependent entity also be FK . Add the ForeignKey attribute over the UserID property in your UserStats class:

public class User
{
    [Key]
    public int UserID {get; set;}
    // other props
}

public class UserStats
{
    [Key, ForeignKey("User")]
    public int UserID {get; set;}
    // other props


    public virtual User User {get; set;}
}

If you want that User nav. property be optional, then you are going to need to change something your model. First, you would need to add a new PK property to your UserStats entity and change UserID FK property as nullable:

public class User
{
    [Key]
    public int UserID {get; set;}
    // other props
}

public class UserStats
{
    [Key]
    public int UserStatsID {get; set;}

    [ForeignKey("User")]
    public int? UserId {get;set;}
    // other props
    public virtual User User {get; set;}
}

But be careful, this last isn't a one to one relationship, in fact is an one to many, but many people use it for the same propose.If you configure this last relationship using Fluent Api it would be this way:

modelBuilder.Entity<UserStats>().HasOptional(us=>us.User).WithMany().HasForeignKey(us=>us.UserId); 
ocuenca
  • 38,548
  • 11
  • 89
  • 102
  • The issue isn't establishing the One to Zero or One relationship, I've had Entity Framework handling that for sometime now. The issue revolves around the fact that, for whatever reason, Entity Framework decides that the UserID property on the UserStats (which has a PK of UserID mind you) should be considered nullable since the User property doesn't have [Required]. – MHollis Aug 24 '15 at 13:46
  • That's odd because the `UserID` property is not nullable and also is PK, anyway you should add the `ForeignKey` data annotation over that property (check this [link](http://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx)) – ocuenca Aug 24 '15 at 14:18
  • Yea, the ForeignKey attribute is definitely required. I really just wish I knew why EntityFramework decides the UserID property is optional, despite being a primary key. – MHollis Aug 24 '15 at 14:25