3

I hope this isn't a duplicate as I have been looking but I was looking more at the reasoning behind this.

I have set up a user object.

public class User
{
    public User()
    {

    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserID { get; set; }
    public Guid UserGuid { get; set; }
    public string Email { get; set; }
    public string Name { get; set; }
    public int CompanyID { get; set; }
    public int StatusID { get; set; }
    [ForeignKey("StatusID")]
    public Status Status { get; set; }
    public int RoleID { get; set; }
    [ForeignKey("RoleID")]
    public UserRole UserRole { get; set; }
}

And the Child Objects

public class UserRole
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int RoleId { get; set; }
    public string Role { get; set; }
}

public class Status
{
    [Key]
    public int StatusId { get; set; }
    public string Description { get; set; }
}

When I call

var testuser = dbContext.User.Where(u => u.CompanyID == 1).FirstOrDefault();

I get users.Status as being null, but users.StatusID = 1.

however, if I call

var status = dbContext.Status.ToList();
var role = dbContext.UserRole.ToList();
var testuser = dbContext.User.Where(u => u.CompanyID == 1).FirstOrDefault();

then call testuser.Status, I can see the correct object related to StatusId of 1.

Can someone explain why this would solve the issue and also how I can make it work without having to call the following beforehand.

var status = dbContext.Status.ToList();

Thanks

Coesy
  • 936
  • 1
  • 10
  • 30
  • 1
    See [Loading Related Entities](https://msdn.microsoft.com/en-us/data/jj574232.aspx). Basically here you need eager loading, e.g. `var testuser = dbContext.User.Include(u => u.Status)....` – Ivan Stoev Sep 22 '16 at 11:59

2 Answers2

5

You can try as shown below.

Note : Use Eager loading with Include()

Eager loading is the process whereby a query for one type of entity also loads related entities as part of the query

using System.Data.Entity;

var testuser = dbContext.User.Where(u => u.CompanyID == 1)
                              .Include(p => p.Status)        
                              .FirstOrDefault();
Sampath
  • 63,341
  • 64
  • 307
  • 441
2

Just use your property like this. Keyword virtual put its property to lazy loading and then you can access the whole object.

public virtual Status Status { get; set; }

And BTW, I edited your class. There are un-needed things, because you can access StatusID by property Status (like int statID = Status.StatusID;) and same to UserRole.

public class User
{
    public User()
   {

   }

   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int UserID { get; set; }
   public Guid UserGuid { get; set; }
   public string Email { get; set; }
   public string Name { get; set; }
   public int CompanyID { get; set; }
   public virtual Status Status { get; set; }
   public virtual UserRole UserRole { get; set; }
   }
}
tadej
  • 701
  • 1
  • 5
  • 22
  • Thanks for this, the lazy loading does the job I need it too but I was wondering what the pros and cons were for eager loading/lazy loading and why I would choose one over the other? – Coesy Sep 22 '16 at 13:03
  • 1
    Here lays answer to your question. I hope it helps! http://stackoverflow.com/a/31366407/5592255 – tadej Sep 23 '16 at 06:58