0

I have a DBContext that is initializing through DropCreateDatabaseAlways class. In the Seed method I have this code:

            base.Seed(context);
            var c1 = new Company { Name = "Samsung"};
            var c2 = new Company { Name = "Microsoft"};
            context.Companies.AddRange(new List<Company>{c1,c2 });
            var phones = new List<Phone>
            {
                new Phone("Samsung Galaxy S5", 20000, c1),
                new Phone("Nokia S1243", 200000, c1),
                new Phone("Nokia 930", 10000, c2),
                new Phone("Nokia 890", 8900, c2)

            };
            context.Phones.AddRange(phones);

            context.SaveChanges();

And if iterate through phones now, I see that phone.Company is not null. But when I do this in any other piece of code, phone.Company IS null. What do I do wrong? A simple piece of code with null phone.Company:

using (var db = new MyDataModel())
        {
            var phonesList = db.Phones.ToList();
            foreach (var p in phones)
            {
                System.Console.WriteLine($"Name: {p.Name} 
                Company: {p.Company}"); // Company is null.
            }
        }

I can access Company using Join with Companies on phone.companyId, so Companies table exists in DB.

My DataModel class:

public class MyDataModel : DbContext
{
    public MyDataModel()
        : base("name=MyDataModel")
    {
    }

    static MyDataModel()
    {
        Database.SetInitializer(new MyContextInializer());
    }

    public DbSet<Company> Companies { get; set; }
    public DbSet<Phone> Phones { get; set; }
}

My Phone class:

namespace DataContext
{


public class Phone
    {
        public Phone()
        {

        }
        public Phone(string name, int price, Company company)
        {
            Name = name;
            Price = price;
            Company = company;
        }

        public int Id { get; set; }

        public string Name { get; set; }

        public int Price { get; set; }

        public int CompanyId { get; set; }

        public Company Company { get; set; }

    }
}

2 Answers 2

1

If you want to automagically load the companies when you load a phone, you need to add the virtual keyword before the Company property.

public class Phone { 

    public Phone() {

    }
    public Phone(string name, int price, Company company)
    {
        Name = name;
        Price = price;
        Company = company;
    }

    public int Id { get; set; }

    public string Name { get; set; }

    public int Price { get; set; }

    public int CompanyId { get; set; }

    public virtual Company Company { get; set; }

}

This tells entity framework to automatically load the linked company whenever you retrieve a phone from the database.

Alternatively you can use eager loading when performing a query on phones.

var phones = MyDataModel.Phones.Include(x => x.Company).ToList();
Sign up to request clarification or add additional context in comments.

4 Comments

that means that all the companies will be load? Even if I need only one Phone?
No it gets only the Company linked to the requested phone(s)
Immorality, and the same occurs if I use that "virtual" approach, right?
Yes, the virtual approach will always include the Company when you retrieve a phone
0

In addition to the cool answer from Immorality, I'll place here these links:

  1. Virtual properties

  2. MSDN - Loading related data strategies

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.