Вы должны знать, что ваш dbContext представляет вашу базу данных. DbSets представляют таблицы в базе данных
В каркасе сущностей столбцы таблиц представлены не виртуальными свойствами ваших классов. Виртуальные свойства представляют отношения между таблицами (один ко многим, многие ко многим, ...)
Ваша база данных будет иметь Recipes
и Ingredient
. Каждый Recipe
будет иметь ноль или более Ingredients
, в то время как каждый Ingredient
используется в нуле или более 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
с обеих сторон, Рецепты и Ингредиенты, структура сущностей может обнаружить, что я разработал многие ко многим. 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;}
}
По моему опыту, поскольку я использую Entity Framework, мне больше не нужно делать (Group-) соединение, я использую коллекции:
Дайте мне все школы со своими учениками
var Result = dbContext.Schools
.Where(school => ...)
.Select(school => new
{
Id = school.Id,
...
Students = school.Students
.Where(student => ...)
.Select(student => new
{
Id = student.Id,
...
})
.ToList(),
});
И аналогичные: дайте мне всех учеников школы, в которой они учатся