简体   繁体   中英

Clarification of one-to-many navigation properties in Entity Framework

I'm a bit confused by conflicting examples of one-to-many model relationships using EF that I'm seeing online.

One video I watched setup a relationship between tables like so:

public class CustomerType
{
    public int Id { get; set; }

    public string Name { get; set; }   
}

public class Customer
{
    public int Id { get; set; }

    public string Name { get; set; }

    public int CustomerTypeId { get; set; }

    public CustomerType CustomerType { get; set; }
}

So a Customer can only have one CustomerType , but a CustomerType can be used by many Customers . This code works fine, I can fetch a Customer 's CustomerType with LINQ using Include .

Now I'm looking at another resource showing the same kind of relationship:

public partial class Standard
{

    public int StandardId { get; set; }
    public string StandardName { get; set; }

    public virtual ICollection<Teacher> Teachers { get; set; }
}

public partial class Teacher
{
    public int TeacherId { get; set; }
    public string TeacherName { get; set; }

    public Nullable<int> StandardId { get; set; }

    public virtual Standard Standard { get; set; }
}

This looks almost the same, except:

  1. In this example, the Standard class (equivalent to my CustomerType ) has a navigation property back to a collection of Teachers , which my first example does not have. Is this just convenient to have if I want to get a list of all teachers for a given standard, or is it necessary to properly set up the relationship?

  2. The properties in the second example are marked virtual and the first are not -- it seems that best practice is to make nav properties virtual, but is there a reason you wouldn't want to do that?

If it matters, I'm using MVC5 and EF6 and I just want to know if one example is right and one is wrong, or just two styles of getting to the same place.

Thanks!

The navigational properties are to make queries easier for the programmer. Your examples are basically the same with the difference that in Standard you can access Teachers through query while in CustomerType you can not access Customers with this CustomerType because you do not have it as a navigational property. Nevertheless, you can always include List<Customer> Customers in Customer Type .

Also it is better to add virtual to your navigational property for the sake of lazy loading.

MSDN

It depends on your needs, if you will never have to get the navigation property and just need a foreign key for sake of data integrity then you can simply add an integer and mark it as a foreign key. ex: instead of having a CustomerType instance, you can simply have a CustomerTypeId and that is it.

As for the virtual keyword, you can add it if you want to have a lazy loading enabled in your DBContext , cause EF generates proxy classes that inherits from your model classes and it overrides the virtual properties to add the needed logic to lazy load the navigation properties.

If you have a lazy loading disabled, then no need to mark any property as virtual

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM