Есть ли способ добавить предложение where в Select внутри Select - мне нужно уменьшить количество возвращаемых JSON - PullRequest
1 голос
/ 13 мая 2019

Этот вопрос касается попыток заставить мой код возвращать меньшее количество результатов, чтобы сделать решение более эффективным, добавив маркер «Где» в «Мой выбор» или полностью переписав запрос.

NB Это с использованием C # .NETРамки 4.7.2.(Мы еще не перешли в Core).

У меня есть следующие объекты: PERSON, PERSON_TYPE, COINS & FINANCIAL_YEAR.

  • PERSON_TYPE (один ко многим),
  • ЧЕЛОВЕК имеет много МОНЕТ (Левая сторона от многих ко многим),
  • МОНЕТА имеет много МИНАНС (Правая сторона от многих ко многим)

(У человека также может быть один или несколько офисов, которые я оставил для полноты).

Например, у человека может быть набор монет 10 на 2016 год, 29 на 2017 год, 37 на 2018 год и т. Д.

Я получаю возвращенные результаты, но при попытке отфильтровать результаты за определенный год, я получаю все возвращенные МОНЕТЫ, но только с 'ФИНАНСОВЫМ ГОДОМ', который я хочу загрузить с отложенной загрузкой.

Я пробовал следующий кодовый запрос

    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, но я также получаю вседругие данные МОНЕТЫ за другие финансовые годы, которые я не хочу, которые делаютответ больше.

Что я хочу, чтобы сделать этот набор результатов более эффективным, так это то, что мои возвращаемые результаты выглядят так:

    [
  {
    "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
        }
      }
    ]
  }
]

EG Это просто возвращает данные Coin за указанный год.

Когда я отображаю эти данные в разбивке по страницам JQuery Datatable, я сразу получаю все результаты обратно, и у меня есть 5000 человек в базе данных, которая, следовательно, возвращает действительно большой файл JSON.

Есть ли способ, с помощью которого я могу добавить предложение Where к этому запросу в подвыборках или другой способ получения данных, который будет более эффективным.

С благодарностью получена любая помощь.

Ответы [ 2 ]

0 голосов
/ 14 мая 2019

Проблема заключается в том, что вы пытаетесь выполнить дополнительную фильтрацию данных, но затем в конце вы выбираете и сериализуете полную сущность Person и все связанные с ней сущности, используя .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, поскольку это будет включать сериализацию всех данных и связанных данных, доступных в сущности. Это может вызвать ленивую загрузку (проблемы с производительностью) и отправить клиенту гораздо больше данных, чем вам нужно, или вы захотите раскрыть их потенциально злонамеренным пользователям.

0 голосов
/ 13 мая 2019

Одним словом, вы можете просто добавить условие 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...