简体   繁体   中英

Defining Foreign Keys EF Code First Model

I am confused about defining foreign keys in a 1:m relationship with EF Code First Approach.

Looking through various tutorials, I see various ways of doing it - not sure what the difference is.

Let's assume that I have 2 models, Product and Category where 1 category has many products.

public class Product
{
    public int ProductId { get; set; }
    public int CategoryId { get; set; }
    public string Name { get; set; }

    // Method 1a
    public virtual ICollection<Category> Categories {get; set; }

    // Method 1b
    public virtual List<Category> Categories {get; set; }

    // Method 1c
    public Category Category {get; set; }

    // Method 1d
    public virtual Category Category { get; set; }
}

public class Category
{
    public int CategoryId { get; set; }
    public string Name { get; set; }

    // Method 2a
    public List<Product> Products { get; set; }

    // Method 2b
    public ICollection<Product> Products { get; set; }

    // Method 2c
    public virtual List<Product> Products { get; set; }

    // Method 2d
    public virtual ICollection<Product> Products { get; set; }
}

public class ExampleContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
}

Product Table: I assume that it doesn't make a difference if I use ICollection / List , but when to use 1a/1b, 1c or 1d?

Category Table: I assume that it doesn't make a difference if I use ICollection / List , but when to use 2a, 2b, 2c?

1a-d

As Product - Category is 1 : n it should be 1c or 1d.

Whether or not to make the property virtual is up to you. If you want it to be lazy loading it should be virtual. If you always use eager loading (eg Include ) you may omit the virtual modifier.

2a-d

It could be any of the options you show.

EF is totally happy with

public (virtual) ICollection<Category> Categories {get; set; }

Again, it's up to you whether you want to enable lazy loading.

There is no need to enforce an ICollection<T> implementation like List<T> . You'll often see that the property is defined as ICollection<T> and that the concrete type will be List<T> or HashSet<T> . As per MSDN the latter provides high-performance set operations. You can initialize the concrete collection in the constructor of the entity.

You don't have to define both Product.Category and Category.Products to express the association. It depends on your business logic which properties you need.

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