C# 为什么我需要.Include()集合
我写了一个非常简单的查询:C# 为什么我需要.Include()集合,c#,.net,entity-framework,linq,icollection,C#,.net,Entity Framework,Linq,Icollection,我写了一个非常简单的查询: var locations = await _context.Locations .Include(x => x.LocationsOfTheUsers) .Include(x => x.Address) .ThenInclude(x => x.County) .Where(CalculateFilters(sear
var locations = await _context.Locations
.Include(x => x.LocationsOfTheUsers)
.Include(x => x.Address)
.ThenInclude(x => x.County)
.Where(CalculateFilters(searchObj))
.ToListAsync(cancellationToken);
每次LocationsOfTheUsers
都是空的,所以我决定.Include(x=>x.LocationsOfTheUsers)
并且我收到了预期的结果,但我不确定为什么我必须包含这些集合,因为它的定义如下:
public class Location
{
public string Title { get; set; }
public long? RegionId { get; set; }
public Region Region { get; set; }
public long? AddressId { get; set; }
public Address Address { get; set; }
public long? CountyId { get; set; }
public County County { get; set; }
public ICollection<LocationsOfTheUsers> LocationsOfTheUsers { get; set; }
}
公共类位置
{
公共字符串标题{get;set;}
公共长?区域ID{get;set;}
公共区域区域{get;set;}
公共长?地址ID{get;set;}
公共广播地址{get;set;}
公共long?CountyId{get;set;}
公共县{get;set;}
公共ICollection LocationsOfTheUsers{get;set;}
}
我认为这将自动包括在内,因为它作为ICollection
存在于Location
类中
那么为什么这里需要locationsoftheuser
上的.Include()
谢谢各位
干杯
我认为这将自动包括在内,因为它作为ICollection存在于Location类中
嗯,它不是自动包含的,可能是出于性能原因,因为相关实体及其递归子实体的图可能相当深
这就是为什么要使用include
方法显式地包含所需的相关实体
另一个选项是使用延迟加载,这意味着只要您访问代码中的导航属性,就会加载相关实体,前提是满足了某些先决条件,并且发生这种情况时上下文仍然存在
有关更多信息,请参阅。我相信您使用的是EntityFrameworkCore。在EntityFramework(EF6)中,默认情况下启用延迟加载,但是,在EntityFrameworkCore中,延迟加载相关实体由单独的包处理
Microsoft.EntityFrameworkCore.Proxies
要启用您正在寻找的行为,请安装上述软件包并添加以下代码
protectedoverride void onconfiguration(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseLazyLoadingProxies();
}
在此之后,将加载相关实体,而无需调用Include
在实体框架中,非虚拟属性表示表的列,虚拟属性表示表之间的关系(一对多、多对多…)
因此,您的财产应定义为:
public virtual ICollection<LocationsOfTheUsers> LocationsOfTheUsers { get; set; }
阅读文档,阅读并展示你的研究成果。反问:为什么实体框架在查询记录时总是要连接所有相关的表(直到有多深)?您可以使用延迟加载(但不能),也可以在需要的地方准确地包含所需内容。@Roxy'Pro:这是否回答了您的问题?
var predicate = CalculateFilters(searchObj)
var queryLocations = dbContext.Locations
.Where(predicate)
.Select(location => new
{
// Select only the location properties that you plan to use
Id = location.Id,
Name = location.Name,
// Locations Of the users:
UserLocations = location.LocationsOfTheUsers
.Select(userLocation => new
{
// again: only the properties that you plan to use
Id = userLocation.Id,
...
// Not needed, you already know the value
// LocationId = userLocation.LocationId
})
.ToList(),
Address = new
{
Street = location.Address.Street,
PostCode = location.Addrress.PostCode,
...
County = location.Address.County.Name // if you only want one property
// or if you want more properties:
County = new
{
Name = location.Address.County.Name,
Abbr = location.Address.Count.Abbr,
...
}),
},
});