我对使用EF Code First Approach以1:m关系定义外键感到困惑。
通过各种教程,我看到了各种方法 - 不确定区别是什么。
我们假设我有2个模型,Product
和Category
,其中1个类别有很多产品。
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; }
}
产品表:
我假设如果我使用ICollection
/ List
,但是何时使用1a / 1b,1c或1d,它没有什么区别?
类别表:
我假设如果我使用ICollection
/ List
,但是何时使用2a,2b,2c,它没有什么区别?
答案 0 :(得分:0)
由于Product
- Category
为1 : n
,因此应为1c或1d。
是否要取得财产virtual
取决于您。如果你想让它延迟加载它应该是虚拟的。如果您始终使用预先加载(例如Include
),则可以省略virtual
修饰符。
它可以是您展示的任何选项。
EF非常满意
public (virtual) ICollection<Category> Categories {get; set; }
同样,您是否要启用延迟加载取决于您。
无需强制ICollection<T>
List<T>
实施,例如ICollection<T>
。您经常会看到该属性定义为List<T>
,具体类型为HashSet<T>
或Product.Category
。根据{{3}},后者提供高性能的集合操作。您可以在实体的构造函数中初始化具体集合。
您无需定义Category.Products
和{{1}}来表达关联。这取决于您的业务逻辑所需的属性。