Преобразуйте вложенный для циклов в единственный оператор LINQ

кто-то может помочь мне превратить эту вложенную структуру в единственный оператор LINQ?

        EventLog[] logs = EventLog.GetEventLogs();
        for (int i = 0; i < logs.Length; i++)
        {
            if (logs[i].LogDisplayName.Equals("AAA"))
            {
                for (int j = 0; j < logs[i].Entries.Count; j++)
                {
                    if (logs[i].Entries[j].Source.Equals("BBB"))
                    {
                        remoteAccessLogs.Add(logs[i].Entries[j]);
                    }
                }
            }
        }
11
задан Grant 6 July 2010 в 05:12
поделиться

5 ответов

Вложенные циклы обычно заканчиваются с несколькими предложениями from (которые преобразуются компилятором в вызовы SelectMany ):

var remoteAccessLogs = from log in EventLogs.GetEventLogs()
                       where log.LogDisplayName == "AAA"
                       from entry in log.Entries
                       where entry.Source == "BBB"
                       select entry;

(Предполагается, что remoteAccessLogs пуст перед этим вызовом, и что вы удачного повторения по нему напрямую - вы можете вызвать ToList () , если вам нужен List .)

Вот форма точечной записи:

var remoteAccessLogs = EventLogs.GetEventLogs()
                                .Where(log => log.LogDisplayName == "AAA")
                                .SelectMany(log => log.Entries)
                                .Where(entry => entry.Source == "BBB");

Или для списка :

var remoteAccessLogs = EventLogs.GetEventLogs()
                                .Where(log => log.LogDisplayName == "AAA")
                                .SelectMany(log => log.Entries)
                                .Where(entry => entry.Source == "BBB")
                                .ToList();

Обратите внимание, что я использовал перегруженный == для строки, так как мне легче читать, чем вызывать метод Equals . Либо будет работать.

14
ответ дан 3 December 2019 в 08:28
поделиться

Попробуйте это:

 EventLog[] logs = EventLog.GetEventLogs(); 
 remoteAccessLogs.AddRange(
   logs.Where(l => l.LogDisplayName.Equals("AAA"))
     .Select(l => l.Entries)
     .Where(le => le.Source.Equals("BBB"));

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

0
ответ дан 3 December 2019 в 08:28
поделиться

Попробуйте следующее:

from log in logs 
where log.LogDisplayName.Equals("AAA")
select 
   (from entry in log.Entries
    where entry.Source.Equals("BBB")
    select entry);
0
ответ дан 3 December 2019 в 08:28
поделиться

Посмотрите:

List<Entries> result = new List<Entries>();

GetEventLogs().Where(x => x.LogDisplayName.Equals("AAA")).ToList().ForEach(delegate(Log en)
{
    en.Entries.Where(y => y.Source.Equals("BBB", StringComparison.InvariantCultureIgnoreCase)).ToList().ForEach(delegate(Entries ent)
    {
        result.Add(ent);
    });
});
0
ответ дан 3 December 2019 в 08:28
поделиться

У меня есть это решение, и я предполагаю, что remoteAccessLogs имеет тип List

remoteAccessLogs.AddRange(

        from log in EventLog.GetEventLogs()
        from entry in log.Entries.Cast<EventLogEntry>()
        select entry
    );

Edit

Я забыл о предложениях where

List<EventLogEntry> remoteAccessLogs = new List<EventLogEntry>();


    remoteAccessLogs.AddRange(

        from log in EventLog.GetEventLogs()
        where log.LogDisplayName.Equals("AAA")
        from entry in log.Entries.Cast<EventLogEntry>()
        where entry.Source.Equals("BBB")
        select entry
    );
0
ответ дан 3 December 2019 в 08:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: