这个问题是关于通过在我的Select上添加一个位置或完全重写查询,使我的代码返回较少的结果,从而使解决方案更有效的方法。
这是使用C#.NET Framework 4.7.2。 (我们尚未迁移到Core。)
我有以下实体:PERSON,PERSON_TYPE,COINS和FINANCIAL_YEAR。
(一个人也可以拥有一个或多个办公室,以保持完整性)
例如一个人可以拥有一组2016年的硬币10、2017年的29个硬币,2018年的37个硬币等等
我得到了返回的结果,但是在尝试过滤特定年份的结果时,我得到了所有返回的硬币,但只有我想懒加载的'FINANCIAL YEAR'。
我尝试了以下代码查询
var persons = appCoreDBContext.PersonRepository.GetAll()
.Where(p => p.Active.Equals(true))
.Select(pl => new
{
pl,
PersonLocs = pl.PersonLocations.Where(ed => ed.EndDate != null)
.Select(o => new
{
o,
office = o.Office
}),
PersonType = pl.PersonType,
PersonCoins = pl.PersonCoins
.Select(yr => new
{
yr,
finYear = yr.FinancialYear
})
.Where(ee => ee.finYear.StartDate.Year == DateTime.Now.Year)
})
.AsEnumerable()
.Select(x => x.pl);
因此这将以JSON返回以下结果
[
{
"id": 1,
"lastModifiedDate": "2019-05-09T11:47:10.193",
"active": true,
"firstName": "Fred",
"lastName": "Flintstone",
"title": "Mr",
"email": "fred.flintstone@slaterockandgravel.com",
"personTypeId": 2,
"personType": {
"id": 2,
"name": "Blue-Collar"
},
"personCoins": [
{
"id": 118,
"lastModifiedDate": "2019-05-12T23:01:33.1566667",
"active": true,
"fullYearValue": 102.0,
"personId": 1,
"financialYearId": 19,
"financialYear": {
"id": 19,
"lastModifiedDate": "2019-04-30T15:33:20.05",
"active": true,
"startDate": "2019-05-01T00:00:01",
"endDate": "2020-04-30T00:00:00",
"label": "FY 2019/2020"
}
},
{
"id": 1,
"lastModifiedDate": "2019-04-29T07:49:41.367",
"active": true,
"fullYearValue": 85.0,
"personId": 1,
"financialYearId": 3,
"financialYear": null
},
{
"id": 2,
"lastModifiedDate": "2019-04-29T07:50:14.747",
"active": true,
"fullYearValue": 65.0,
"personId": 1,
"financialYearId": 2,
"financialYear": null
},
{
"id": 3,
"lastModifiedDate": "2019-04-29T07:50:41.307",
"active": true,
"fullYearValue": 45.0,
"personId": 1,
"financialYearId": 1,
"financialYear": null
},
{
"id": 109,
"lastModifiedDate": "2019-05-09T18:02:34.52",
"active": true,
"fullYearValue": 100.0,
"personId": 1,
"financialYearId": 20,
"financialYear": null
},
{
"id": 112,
"lastModifiedDate": "2019-05-09T19:00:09.787",
"active": true,
"fullYearValue": 101.0,
"personId": 1,
"financialYearId": 21,
"financialYear": null
},
{
"id": 115,
"lastModifiedDate": "2019-05-09T19:04:15.853",
"active": true,
"fullYearValue": 101.0,
"personId": 1,
"financialYearId": 22,
"financialYear": null
}
],
"personLocations": [
{
"id": 1,
"lastModifiedDate": "2019-04-25T10:19:07.193",
"active": true,
"startDate": "2018-10-29T09:00:00",
"endDate": null,
"office": {
"id": 2,
"lastModifiedDate": "2019-04-25T10:16:37.9533333",
"active": true,
"name": "Bedrock",
"address1": "The Quarry",
"address2": "Bedrock",
"address3": "Prehistorica",
"zipcode": "YabbaDabbaDoo",
"openingDate": "1992-06-01T09:00:00",
"closingDate": null,
"officialCurrencyId": 1,
"officialCurrency": null,
"countryId": 1,
"country": null
}
}
]
}
]
正如您在上面看到的那样,我确实获得了我想要的2019年的会计年度信息,但是我也获得了我不想获得的其他会计年度的所有其他COIN数据,这使得响应变大了。
我想要让我的返回结果看起来像这样
[
{
"id": 1,
"lastModifiedDate": "2019-05-09T11:47:10.193",
"active": true,
"firstName": "Fred",
"lastName": "Flintstone",
"title": "Mr",
"email": "fred.flintstone@slaterockandgravel.com",
"personTypeId": 2,
"personType": {
"id": 2,
"name": "Blue-Collar"
},
"personCoins": [
{
"id": 118,
"lastModifiedDate": "2019-05-12T23:01:33.1566667",
"active": true,
"fullYearValue": 102.0,
"personId": 1,
"financialYearId": 19,
"financialYear": {
"id": 19,
"lastModifiedDate": "2019-04-30T15:33:20.05",
"active": true,
"startDate": "2019-05-01T00:00:01",
"endDate": "2020-04-30T00:00:00",
"label": "FY 2019/2020"
}
}
],
"personLocations": [
{
"id": 1,
"lastModifiedDate": "2019-04-25T10:19:07.193",
"active": true,
"startDate": "2018-10-29T09:00:00",
"endDate": null,
"office": {
"id": 2,
"lastModifiedDate": "2019-04-25T10:16:37.9533333",
"active": true,
"name": "Bedrock",
"address1": "The Quarry",
"address2": "Bedrock",
"address3": "Prehistorica",
"zipcode": "YabbaDabbaDoo",
"openingDate": "1992-06-01T09:00:00",
"closingDate": null,
"officialCurrencyId": 1,
"officialCurrency": null,
"countryId": 1,
"country": null
}
}
]
}
]
E.G。它只是返回指定年份的硬币数据。
当我在分页的JQuery Datatable中显示此数据时,我立即获得了所有结果,并且数据库中有5000个人,因此返回了一个非常大的JSON文件。
有没有一种方法可以在子选择内的此查询上添加Where子句,或者通过另一种方法获取数据,这将更加有效。
非常感谢您的帮助。
答案 0 :(得分:0)
您只需在财务年度部分添加一个where子句即可:
var persons = appCoreDBContext.PersonRepository.GetAll()
.Where(p => p.Active.Equals(true))
.Select(pl => new
{
pl,
PersonLocs = pl.PersonLocations.Where(ed => ed.EndDate != null)
.Select(o => new
{
o,
office = o.Office
}),
PersonType = pl.PersonType,
PersonCoins = pl.PersonCoins
.Where(yr => yr.FinancialYear != null)
.Select(yr => new
{
yr,
finYear = yr.FinancialYear
})
.Where(ee => ee.finYear.StartDate.Year == DateTime.Now.Year)
})
.AsEnumerable()
.Select(x => x.pl);
答案 1 :(得分:0)
问题是您试图对数据进行子过滤,但是最后您选择并使用.Select(x => x.pl)
尝试一下:
.Select(pl => new PersonViewModel
{
pl.id,
pl.lastModifiedDate,
pl.active,
pl.firstName,
pl.lastName,
pl.email,
pl.personType.Select(pt => new PersonTypeViewModel
{
pt.id,
pt.name
}),
personLocs = pl.PersonLocations.Where(ed => ed.EndDate != null)
.Select(o => new PersonLocationViewModel
{
id = o.OfficeId,
office = o.Office
}),
personCoins = pl.PersonCoins
.Select(yr => new PersonCoinViewModel
{
finYear = yr.FinancialYear
})
.Where(ee => ee.finYear.StartDate.Year == DateTime.Now.Year)
}).AsEnumerable();
您将需要为要发送回的数据结构定义视图模型,因为我认为您无法返回/序列化匿名类型。
基本上,只需选择要不选择实体的字段和相关数据即可。您应该避免返回实体,包括在返回的DTO / ViewModel内部引用实体,因为这将包括序列化实体中可用的所有数据和相关数据。这可能会触发延迟负载(性能问题),并且向客户端发送的数据要多于您所需要的,或者希望向潜在的恶意用户公开。