Как я могу добавить .Where в .Select в объект с помощью LINQ? - PullRequest
2 голосов
/ 14 марта 2020

У меня есть LINQ Query, который я использую. Я хочу упорядочить данные в Start, а затем выбрать данные для AndroidSpeeds или IOSSpeeds в зависимости от того, имеет ли извлеченная строка значение Android или Ios, установленное в значение true.

Вот мой запрос:

List<LogStart> Start1 = Start
    .Where(x => x.IsPhysical == true)
    .OrderBy(g => g.DateYYMMDD)
    .Select(g => new Start2
    {
        AndroidDBSpeed = (int?)g.Where(gx => gx.IsAndroid).Select(gx => (int?)gx.DBSpeed).DefaultIfEmpty(),
        AndroidCPUSpeed = (int?)g.Where(gx => gx.IsAndroid).Select(gx => (int?)gx.CPUSpeed).DefaultIfEmpty(),
        IOSDBSpeed = (int?)g.Where(gx => gx.IsIos).Select(gx => (int?)gx.DBSpeed).DefaultIfEmpty(),
        IOSCPUSpeed = (int?)g.Where(gx => gx.IsIos).Select(gx => (int?)gx.CPUSpeed).DefaultIfEmpty(),
    })
    .ToList();

Однако есть проблема. Это указывает на. Где и говорится, что

Program.cs (46,46): Ошибка CS1061: «LogStart» не содержит определения «Где» и нет доступного метода расширения «Где», принимающего первый аргумент может быть найден тип 'LogStart' (вам не хватает директивы using или ссылки на сборку?) (CS1061) (Cosmos)

У кого-нибудь есть идеи, что может быть не так и как это можно исправить ?

Для справки , следующее утверждение в том же файле работает нормально:

   List<LogStart> Start2 = Start
        .Where(x => x.IsPhysical == true)
        .GroupBy(x => x.DateYYMMDD)
        .OrderBy(g => g.Key)
        .Select(g => new Start2
        {
            DateYYMMDD = g.Key,
            Devices = g.Count(),
            AndroidDBSpeed = (int?) g.Where(gx => gx.IsAndroid).Select(gx => (int?) gx.DBSpeed).DefaultIfEmpty().Average(),
            AndroidCPUSpeed = (int?)g.Where(gx => gx.IsAndroid).Select(gx => (int?)gx.CPUSpeed).DefaultIfEmpty().Average(),
            IOSDBSpeed = (int?)g.Where(gx => gx.IsIos).Select(gx => (int?)gx.DBSpeed).DefaultIfEmpty().Average(),
            IOSCPUSpeed = (int?)g.Where(gx => gx.IsIos).Select(gx => (int?)gx.CPUSpeed).DefaultIfEmpty().Average(),
        })
        .ToList();

Ответы [ 3 ]

3 голосов
/ 14 марта 2020

Группировка - это то, что делает вторую работу.

Если вы не хотите группировать, то я подозреваю, что вы ищете что-то вроде

var Start1 = Start
.Where(x => x.IsPhysical == true)
.OrderBy(g => g.DateYYMMDD)
.Select(g => new Start2
{
    AndroidDBSpeed  = g.IsAndroid ? (int?) g.DBSpeed :  (int?) null,
    AndroidCPUSpeed = g.IsAndroid ? (int?) g.CPUSpeed : (int?) null,
    IOSDBSpeed      = gx.IsIos    ? (int?) g.DBSpeed  : (int?) null,
    IOSCPUSpeed     = gx.IsIos    ? (int?) g.CPUSpeed : (int?) null,
})
.ToList();
0 голосов
/ 14 марта 2020
using System.Linq //Add this to the namespace, if you have not added

В C# LINQ предоставляет возможность фильтровать данные, используя Where, Select, GroupBy et c, и они называются методами расширения. Чтобы использовать эти методы расширения, вам нужно добавить System.Linq пространство имен, которое является частью сборки System.Core, которая обеспечивает доступ к классам, поддерживающим запросы, использующие встроенный в язык запрос

Программа .cs (46,46): Ошибка CS1061: «LogStart» не содержит определения «Где», и нет доступного метода расширения «Где», где можно найти первый аргумент типа «LogStart» (вы пропустили директиву using или ссылка на сборку?) (CS1061) (Космос)

РЕДАКТИРОВАТЬ : Из последующих обновлений

Для использования Где , вы должны убедиться, что тип реализует IEnumerable , а в этой строке g.Where(gx => gx.IsAndroid). g имеет тип LogStart и не реализует IEnumerable , поэтому вы не может использовать расширение Where для него

Обратите внимание на мои комментарии, что следующий оператор c# в том же файле работает просто отлично.

Это работает, потому что ваш делают GroupBy на Collection , что означает, что (int?) g.Where(gx => gx.IsAndroid) g имеет тип IGrouping , который является IEnumerable, который дополнительно имеет ключ

Чтобы решить, с вашим исходным кодом вы можете попробуйте Cast<IEnumberable>, затем используйте .Where, как показано ниже

List<LogStart> Start1 = Start
    .Where(x => x.IsPhysical == true)
    .OrderBy(g => g.DateYYMMDD).Cast<IEnumerable<LogStart>>()
    List<LogStart> Start1 = Start
    .Where(x => x.IsPhysical == true)
    .OrderBy(g => g.DateYYMMDD).Cast<IEnumerable<LogStart>>()
   .Select(g => new Start2
    {
        AndroidDBSpeed = (int?)g.Where(gx => gx.IsAndroid).Select(gx => (int?)gx.DBSpeed).DefaultIfEmpty(),
        AndroidCPUSpeed = (int?)g.Where(gx => gx.IsAndroid).Select(gx => (int?)gx.CPUSpeed).DefaultIfEmpty(),
        IOSDBSpeed = (int?)g.Where(gx => gx.IsIos).Select(gx => (int?)gx.DBSpeed).DefaultIfEmpty(),
        IOSCPUSpeed = (int?)g.Where(gx => gx.IsIos).Select(gx => (int?)gx.CPUSpeed).DefaultIfEmpty(),
    })
    .ToList();
0 голосов
/ 14 марта 2020

Это так просто, как только может. .Где есть метод расширения. Проверьте свои операторы использования - если вы не используете правильное пространство имен (iir c System.Linq), вы не сможете получить этот метод.

И, очевидно, Start должен иметь тип, поддерживаемый LINQ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...