我使用Entity Framework代码第一种方法来创建mydatabase。我有四个简单的课程:
我的第一堂课是分类:
public class Category
{
[Key]
public int CategoryId { set; get; }
public DateTime CreatedOn { set; get; }
public int? ParentCategoryId { set; get; }
public virtual ICollection<Product> Products { set; get; }
public virtual ICollection<CategoryLanguage> CategoriesLanguages { set; get; }
public Category()
{
this.Products = new HashSet<Product>();
this.CategoriesLanguages = new HashSet<CategoryLanguage>();
}
}
我的第二课--CategoryLanguage.cs
public class CategoryLanguage
{
[Key]
public int Id { set; get; }
[Required]
public string Title { set; get; }
public int CategoryId { set; get; }
public virtual Category Category { set; get; }
public int LanguageId { set; get; }
public virtual Language Language { set; get; }
}
我的第三课 - Product.cs
public class Product
{
[Key]
public int ProductId { set; get; }
public decimal Price { set; get; }
public int Quantity { set; get; }
public string Image { set; get; }
public virtual ICollection<Category> Categories { set; get; }
public virtual ICollection<ProductLanguage> ProductLanguages { set; get; }
public Product()
{
this.Categories = new HashSet<Category>();
this.ProductLanguages = new HashSet<ProductLanguage>();
}
}
和我的上一堂课
public class ProductLanguage
{
[Key]
public int Id { set; get; }
public int ProductId { set; get; }
public virtual Product Product { set; get; }
public int LanguageId { set; get; }
public virtual Language Language { get; get; }
public string Name { set; get; }
public string ShortDescription { set; get; }
public string Description { set; get; }
}
这是我的DbContext
public class EcommerceDBContext:DbContext
{
public EcommerceDBContext() : base("DefaultConnection"){}
public DbSet<Category> Categories { set; get; }
public DbSet<CategoryLanguage> CategoriesLanguages { set; get; }
public DbSet<Product> Products { set; get; }
public DbSet<ProductLanguage> ProductsLanguages { set; get; }
}
很奇怪在我的数据库中,我看到另一个表ProductCategories
,其中有两列:Product_ProductID
和Category_CategoryID
。
因此,Product
表和Categories
表具有多对多的关系,而且我使用延迟加载是正确的,这是真的。能够加载Category
的所有产品;以及产品的所有类别。我只是很好奇代码优先引擎如何决定制作这个表。 (在所有集合都是虚拟的之后,它们不应该存在于数据库中)。
答案 0 :(得分:1)
您已用
字样回答了自己的问题[产品表和类别表具有多对多关系
延迟加载和virtual
无关 - virtual
只是通过在运行时创建代理类型来启用延迟加载(请参阅下面的参考资料)。
代码优先只是检测到两个表与多对多关系链接,因为在每个类中,您具有相关类的ICollection
属性:P
有许多{{1 }和C
有很多C
。因此,它使用命名约定P
创建连接表†,并使用关系每一侧的主键列。
请参阅MSDN:加载相关实体"Lazy Loading"和"Turning off lazy loading for specific navigation properties",<LeftTable><RightTable><plural modifier>
几乎被提及为这些部分中的传递注释,但这是延迟加载的原因。
† 加入,链接或映射表,具体取决于您的偏好
答案 1 :(得分:0)
当EF Code First决定如何将模型类映射到数据库模式时,它会检查模型类,尤其是这些类之间的导航属性。在您的示例中,它发现Category
有一个Products
集合(一个类别包含许多产品),并且产品有一个{{1} } 集合(一个产品有许多类别)。从此EF得出结论,两个实体之间的关系是多对多。为了将其映射到关系数据库,需要一个链接表,它是引入的Categories
表。
当然还有更多细节可以控制映射 - 比如数据注释和Fluent API。但是对于您的具体示例,映射仅依赖于约定和类定义。
BTW:您的导航属性为ProductCategories
并不重要。实体和数据库模式之间的映射与导航属性virtual
(支持延迟加载)无关。