C# 具有n+;1期

C# 具有n+;1期,c#,.net-core,ef-core-2.2,C#,.net Core,Ef Core 2.2,我有一个包含三个子查询的查询,我的问题是子查询针对每个国家(n+1)运行 由于主查询大约有70行,因此我简化了查询以使其更易于阅读,并更改了域以使其更易于理解 我已经尝试在子查询中包含Cities/Mountains/Rivers和running.ToList(),但没有效果 // The CountryDto class I'm selecting to. public class CountryDto { public string CountryName { get; set; }

我有一个包含三个子查询的查询,我的问题是子查询针对每个国家(n+1)运行

由于主查询大约有70行,因此我简化了查询以使其更易于阅读,并更改了域以使其更易于理解

我已经尝试在子查询中包含Cities/Mountains/Rivers和running.ToList(),但没有效果

// The CountryDto class I'm selecting to.
public class CountryDto
{
    public string CountryName { get; set; }
    public IEnumerable<CityDto> CityDtos { get; set; }
    public IEnumerable<MountainDto> MountainDtos { get; set; }
    public IEnumerable<RiverDto> RiverDtos { get; set; }
}
// The query
var query = _db.Countries
    .Select(country => new CountryDto
    {
        CountryName = country.Name,
        CityDtos = country.Citites
            .Where(city => city.Population > 10000)
            .Select(city => new CityDto
            {
                Name = city.Name,
            }),
        MountainDtos = country.Mountains
            .Where(mountain => mountain.Height > 100)
            .Select(mountain => new MountainDto
            {
                Name = mountain.Name,
            }),
        RiverDtos = country.Rivers
            .Where(river => river.Length > 1000)
            .Select(river => new RiverDto
            {
                Name = river.Name,
            }),
    })
    .Where(c => c.CityDtos.Any() || c.MountainDtos.Any() || c.RiverDtos.Any());

var totalCount = query.Count();
var countries = await query.ToListAsync();
//我要选择的CountryDto类。
公共类国家
{
公共字符串CountryName{get;set;}
公共IEnumerable CityDtos{get;set;}
公共IEnumerable MountainDtos{get;set;}
公共IEnumerable RiverDtos{get;set;}
}
//询问
var query=\u db.Countries
.选择(国家=>新国家/地区到
{
CountryName=国家。名称,
CityDtos=国家。城市
.Where(城市=>城市人口>10000)
.选择(城市=>new CityTo
{
Name=city.Name,
}),
山地
.Where(山=>山.高度>100)
.选择(mountain=>new MountainDto
{
Name=山。Name,
}),
RiverDtos=乡村。河流
.Where(河流=>河流长度>1000)
.选择(河流=>新建河流到
{
Name=river.Name,
}),
})
其中(c=>c.CityDtos.Any()| | c.MountainDtos.Any()| | c.RiverDtos.Any());
var totalCount=query.Count();
var countries=wait query.ToListAsync();

实体框架核心支持在客户机上评估的部分查询以及推送到数据库的部分查询。由数据库提供者决定将在数据库中计算查询的哪些部分

在您的情况下,所有
。我想任何
部分都是在客户端进行评估的。您可以将代码配置为引发异常以进行客户端评估

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFQuerying;Trusted_Connection=True;")
        .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
}

有关更多信息

Entity Framework Core支持在客户机上评估部分查询,并将部分查询推送到数据库。由数据库提供者决定将在数据库中计算查询的哪些部分

在您的情况下,所有
。我想任何
部分都是在客户端进行评估的。您可以将代码配置为引发异常以进行客户端评估

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFQuerying;Trusted_Connection=True;")
        .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
}

有关更多信息,请参见最后将查询拆分为一个
.Where()
部分用于计数,另一个
部分用于结果,这消除了我的n+1问题

var query = await _db.Countries
    .Include(c => c.Cities)
    .Include(c => c.Mountains)
    .Include(c => c.Rivers)
    .Where(c => c.Cities.Any(city => city.Population > 10000)
        || c.Mountains.Any(mountain => mountain.Heigh > 1000)
        || c.River.Any(river => river.Length > 100000))
    .Where(c => c.Cities.Any() || c.Mountains.Any() || c.Rivers.Any())
    .ToListAsync();

var totalCount = query.Count();

var countries = query
    .Select(country => new CountryDto
    {
        CountryName = country.Name,
        CityDtos = country.Citites
            .Select(city => new CityDto
            {
                Name = city.Name,
            }),
        MountainDtos = country.Mountains
            .Select(mountain => new MountainDto
            {
                Name = mountain.Name,
            }),
        RiverDtos = country.Rivers
            .Select(river => new RiverDto
            {
                Name = river.Name,
            }),
    })
    .ToList();

最后将查询拆分为计数的
.Where()
部分和结果的
.Select()
部分,从而删除了我的n+1问题

var query = await _db.Countries
    .Include(c => c.Cities)
    .Include(c => c.Mountains)
    .Include(c => c.Rivers)
    .Where(c => c.Cities.Any(city => city.Population > 10000)
        || c.Mountains.Any(mountain => mountain.Heigh > 1000)
        || c.River.Any(river => river.Length > 100000))
    .Where(c => c.Cities.Any() || c.Mountains.Any() || c.Rivers.Any())
    .ToListAsync();

var totalCount = query.Count();

var countries = query
    .Select(country => new CountryDto
    {
        CountryName = country.Name,
        CityDtos = country.Citites
            .Select(city => new CityDto
            {
                Name = city.Name,
            }),
        MountainDtos = country.Mountains
            .Select(mountain => new MountainDto
            {
                Name = mountain.Name,
            }),
        RiverDtos = country.Rivers
            .Select(river => new RiverDto
            {
                Name = river.Name,
            }),
    })
    .ToList();

那么您要如何处理这个查询呢?据我所见,
Country
似乎没有
cittes
字段,因此
c.cittes.Any()
在最后一行似乎不合法(您使用
Cities=…
)。你试过把
部分移到
选择部分上方的
位置吗?@er sho我希望查询作为一个查询进行评估,现在每个子查询都针对每个国家进行评估。@Rafalon Yep,我的坏孩子,忘了更新内部投影上的
位置
ToList
(或者是唯一可能的方法)请看。正如其他人所说,尝试消除影响的
。如果
ToList
没有帮助,你就无能为力了。那么你该如何处理这个查询呢?据我所见,
Country
似乎没有
Citites
字段,所以
c.Citites.Any()
在最后一行似乎不合法(你使用
Cities=…
)。你试过把
部分移到
选择部分上方的
位置吗?@er sho我希望查询作为一个查询进行评估,现在每个子查询都针对每个国家进行评估。@Rafalon Yep,我的坏孩子,忘了更新内部投影上的
位置
ToList
(或者是唯一可能的方法)请看。正如其他人所说,尝试消除影响的
。如果
ToList
不起作用,您将无能为力。