在LINQ中,我写了一个简单的查询,我正在使用ID属性搜索动物。但是,我还使用Include属性包括动物所属的农场。
我想在SQL中编写相同的LINQ查询,其中我可以包括Farm。如何使用SQL包含Farm。下面是一个不完整的SQL语法。有谁能帮我一下吗?
LINQ
await _dbContext.Animals.Where(x => x.id == 1)
.Include(x => x.Farm)
.ToListAsync();
/p>select * from Animals where id = 1;
显然,您的数据库中有一个包含Animals的表和一个包含Farms的表。动物和农场之间似乎存在一对多的关系:每个农场都有零只或更多的动物;每个动物都生活在一个农场,即外键所指的农场。
我认为你会有类似以下的类:
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;}
}
我想在SQL中编写相同的LINQ查询,其中我可以包含Farm.
一个小技巧:如果你想知道实体框架生成的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
你必须加入农场的动物,并且只保留ID = 1的动物:参见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
不要使用">"去拿东西。如果农场[10]有5000只鸡,那么每只鸡都有一个值为10的外键。如果使用">"当您已经知道外键的值时,您将传输此值超过5000次。
有改进的空间
当使用实体框架获取数据时,总是使用Select,并且只选择你计划使用的属性,即使你选择了所有属性。只有当您计划更改/更新已获取的数据时,才可以省略Select和/或使用Include。
原因是,不使用Select抓取数据效率不高。
如果你没有使用Select来抓取数据,实体框架会把抓取到的数据放到DbContext.ChangeTracker
中,并附上一份拷贝。你会得到副本的参考。无论何时更改所获取项的属性,都要更改ChangeTracker中的副本。当您调用DbContext.SaveChanges
时,将原始文件与副本进行比较,每个属性进行比较,以查看哪些属性被更改,从而需要在数据库中更新。
因此,如果您不打算更改已获取的数据,那么将此数据和副本放在ChangeTracker中将是浪费处理能力。因此:总是使用Select,除非你打算更新已获取的数据。