显然,您的数据库有一个包含 Animals 的表和一个包含 Farms 的表。动物和农场之间似乎存在一对多的关系:在每个农场上生活着零个或多个动物;每个 Animal 都生活在一个 Farm 中,即外键所指的 Farm。
我认为你会有类似于以下的类:
class Farm
{
public int Id {get; set;}
public string Name {get; set;}
... // etc
// Every Farm has zero or more Animals (one-to-many)
public virtual ICollection<Animal> {get; set;}
}
class Animal
{
public int Id {get; set;}
public string Name {get; set;}
... // etc
// Every Animal lives on exactly one Farm, using foreign key
public int FarmId {get; set;}
public virtual Farm Farm {get; set;}
}
我想在可以包含 Farm 的 SQL 中编写相同的 LINQ 查询。
一个小技巧:如果你想知道Entity Framework生成的SQL代码,使用属性DbContext.Database.Log。
using (var dbContext = new DbContext())
{
// Log generated SQL to debug window:
dbContext.Database.Log = System.Diagnostics.Debug.Write;
// execute your LINQ:
var fetchedAnimals = _dbContext.Animals.Where(x => x.id == 1)
.Include(x => x.Farm)
.ToList();
}
编写自己的 SQL
您必须加入 Animals with Farms,并且只保留 ID = 1 的 Animal:
见SQL Join
// Select only the properties of Animals and Farms that you actually plan to use
SELECT Animals.Id, Animals.Name, ...,
Farms.Id, Farms.Name, ...
FROM Animals INNER JOIN Farms
ON Animals.FarmId = Farm.Id
WHERE Animals.Id = 1
您不应该使用“”来获取所有内容。如果 Farm [10] 有 5000 只鸡,那么每只鸡都会有一个值为 10 的外键。如果你使用“”,你将传递这个值 10 超过 5000 次,而你已经知道外键。
还有改进的余地
使用实体框架获取数据时,始终使用 Select,并且只选择您计划使用的属性,即使您选择所有属性。如果您计划更改/更新获取的数据,请仅省略 Select 和/或使用 Include。
原因是,不使用 Select 获取数据效率不高。
如果你在不使用 Select 的情况下获取数据,实体框架会将获取的项目与获取的项目的副本一起放在 DbContext.ChangeTracker 中。您将获得对副本的引用。每当您更改获取项目的属性时,都会更改 ChangeTracker 中的副本。当你调用DbContext.SaveChanges时,将原始与副本进行比较,每个属性的属性以查看哪些属性发生了更改,因此需要在数据库中进行更新。
因此,如果您不打算更改获取的数据,那么将这些数据和副本放入 ChangeTracker 会浪费处理能力。因此:除非您打算更新获取的数据,否则请始终使用 Select。