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?
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.
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.