3 回答
TA贡献1852条经验 获得超7个赞
EF 足够聪明,不会创建重复的表,最好将DbSet<>
.
当你有一个带有名称的类Ingredient
并且你在其中引用它时Recept
,将只有一个带有名称Ingredient
的表并且你不能有两个具有相同名称的表所以即使你想要也不会创建重复的表。
TA贡献1876条经验 获得超6个赞
正如您已经说过的,EF 将Ingredient在属性中查找类型Recipe并创建Ingredients表。这意味着,Ingredients即使您省略了,也会创建该表public DbSet<Ingredient> Ingredient { get; set; }。然而,仅仅因为你不需要public DbSet<Ingredient> Ingredient { get; set; },并不意味着你不能拥有它。您可以随意包含它,它不会造成任何伤害,也不会创建任何副本。
添加public DbSet<Ingredient> Ingredient { get; set; }到您的允许您直接从上下文DbContext访问条目:Ingredient
MyContext context = ...
var ingredients = context.Ingredients;
否则,您将不得不通过属性访问Ingredient条目:Recipes
MyContext context = ...
var recipe = context.Recipes...;
var ingredients = recipe.Ingredients;
摘要:什么时候应该将类包含在 DbContext 中?
当该类未被属于
DbContext
. 将类添加到DbContext
将确保它已映射。当您希望能够直接从 DbContext 实例访问该类的条目时。例如
var ingredients = context.Ingredients
。当您想确保该类将被映射,并且不想依赖它被其他映射类引用时。
因此,要回答您的问题“我们应该在 DbContext 中包含所有类吗?” : 你可以,这是完全好的方法。这样您将确保所有类(您想要映射)都将被映射,而不必依赖于它们被其他类引用。
TA贡献1842条经验 获得超12个赞
您必须知道您的 dbContext 代表您的数据库。DbSets 表示数据库中的表
在实体框架中,表的列由类的非虚拟属性表示。虚拟属性表示表之间的关系(一对多,多对多,......)
您的数据库将有Recipes和Ingredient。EveryRecipe将有零个或多个Ingredients,而 everyIngredient用于零个或多个Recipes:一个简单的多对多关系。
您将拥有表Recipes和Ingredients,因此您的 dbContext 将拥有DbSets它们:
class MyDbContext : DbContext
{
public DbSet<Recipe> Recipes {get; set;}
public DbSet<Ingredient> Ingredients {get; set;}
}
class Recipe
{
public int Id {get; set;} // primary key
... // other columns
// every Recipe has zero or more ingredients (many-to-many)
public virtual ICollection<Ingredient> Ingredients {get; set;}
}
class Ingredient
{
public int Id {get; set;} // primary key
... // other columns
// every Ingredient is used in zero or more Recipes( many-to-many)
public virtual ICollection<Recipe> Recipes {get; set;}
}
因为我virtual两边都用了,Recipes和Ingredients,entity framework可以检测到我设计的是多对多。实体框架甚至会为我创建一个联结表,我不必声明它。
// Fetch all Desserts with their Bitter ingredients
var desertsWithoutSugar = myDbContext.Recipes
.Where(recipe => recipy.Type == RecipyType.Dessert)
.Select(recipe => new
{
// select only the properties that I plan to use:
Id = recipe.Id,
Name = recipe.Name,
...
// not needed: you know the value: Type = recipe.Type
Ingredients = recipe.Ingredients
.Where(ingredient => ingredient.Taste == Taste.Bitter)
.Select(ingredient => new
{
// again: only the properties you plan to use
Id = ingredient.Id,
Name = ingredient.Name,
})
.ToList(),
})
实体框架了解您的多对多关系,并且足够聪明,可以检测到三个表(包括连接表)需要(组)连接。
如果你想设计一个一对多的关系,例如一个学校和他的学生,你virtual ICollection可以在一侧声明唯一。另一方获得外键。这是您表中的一列,因此是非虚拟的
class School
{
public int Id {get; set;}
...
// every School has zero or more Students (one-to-many)
public virtual ICollection<Student> Students {get; set;}
}
class Student
{
public int Id {get; set;}
...
// Every Student studies at one School, using foreign key
public int SchoolId {get; set;}
public virtual School School {get; set;}
}
public SchoolContext : DbContext
{
public DbSet<School> Schools {get; set;}
public DbSet<Student> Students {get; set;}
}
根据我的经验,由于我使用实体框架,我几乎不必再进行 (Group-)join,我使用集合:
给我所有的学校和他们的学生
var Result = dbContext.Schools
.Where(school => ...)
.Select(school => new
{
Id = school.Id,
...
Students = school.Students
.Where(student => ...)
.Select(student => new
{
Id = student.Id,
...
})
.ToList(),
});
类似的:给我所有学生和他们就读的学校
- 3 回答
- 0 关注
- 126 浏览
添加回答
举报