Sharp Kid Sharp Kid - 1 month ago 3
ASP.NET (C#) Question

The value of the navigation property of my EntityFramework class created in code fist mode always be null

I am a beginner of EntityFramework. The codes below is extracted form my project.

public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int UserId { get; set; }

public virtual int UserType { get; set; }
}

public class Person : User
{
public override int UserType
{
get
{
return 0;
}
set
{
base.UserType = 0;
}
}

public string PersonName { get; set; }

public ICollection<Sunny.Models.WorkExperience> WorkExperiences { get; set; }
}

public class WorkExperience
{
[Key]
public int ExperienceId { get; set; }

public int PersonId { get; set; }

public string Job { get; set; }

[ForeignKey("PersonId")]
public Person Person { get; set; }
}

public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
this.Map<User>(user => user.ToTable("User"));
this.Map<Person>(person => person.ToTable("Person"));
}
}

public class DbContext : System.Data.Entity.DbContext
{
public DbContext() : base("name=Model")
{
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new UserConfiguration());
modelBuilder.Conventions.Remove<Conventions.PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
}

public DbSet<User> Users { get; set; }
public DbSet<Person> Persons { get; set; }
public DbSet<WorkExperience> WorkExperiences { get; set; }
}

static void Main(string[] args)
{
DbContext context = new Models.DbContext();

Person person = new Models.Person();
person.UserId = 1;
person.PersonName = "Name";
context.Persons.Add(person);

WorkExperience experience = new Models.WorkExperience();
experience.PersonId = 1;
experience.Job = "Coder";
context.WorkExperiences.Add(experience);

context.SaveChanges();

context = new DbContext();
Console.Write(context.WorkExperiences.First().Person == null);
Console.Read();
}


The running result of the Main method above is displaying true ,That is to say ,the value of the property WorkExperiences.Person always be null .But i have inserted data into the tables .

How to let the property WorkExperiences.Person load with the referenced key value ? Thanks in advance for any help.

PMV PMV
Answer

Entity framework won't automatically load associated entities unless you specifically query for them.The reason is that it would be too easy to load far more than you expected if you always loaded all navigation properties - you might end up pulling most of your database back even on a simple query, if you have a lot of relationships. Imagine if you went to Amazon and it ran a query for your orders, which then included all products in those orders, which then included all sellers from those products, which then included all products from those sellers, ...

Entity Framework gives you several techniques to control when you want to load related data.

You can use DbExtensions.Include() to force it to include a related entity with the original query, which means one trip to the database:

Console.Write(context.WorkExperiences.Include(w => w.Person).First().Person == null);

Alternatively, you can use .Load() to force the load of an entity which isn't loaded:

var firstWE = context.WorkExperiences.First();
firstWE.Reference("Person").Load();
Console.Write(firstWE.Person == null);

Or you can enable lazy loading, which will make it load on demand the first time you access the property. You do this by adding virtual to it (which allows EF the ability to add some code to your property and load on demand):

public virtual Person Person { get; set; }
Comments