Как избежать использования IF-Else и использовать встроенное условие if внутри функции .where ()?

#c# #entity-framework #linq #c#-4.0 #linq-to-sql

Вопрос:

  q = q.Where(s => 
                    !matchingRecords.Contains(s.Id)
                    || (s.SecId != null)
                 );
 

но соответствующие записи могут быть пустыми или содержать 0 элементов, так как это список. Таким образом, в этом случае в приведенном выше коде произойдет сбой. Я хочу проверить, содержит ли это только в том случае, если
соответствующие записи не являются нулевыми и не содержат каких-либо других элементов.

Один из способов- IF-Else заблокировать и повторить код, но я хочу сделать это встроенным, как ?

Комментарии:

1. q = matchingRecords?.Count() > 0 ? q.Where(s => !matchingRecords.Contains(s.Id) || (s.SecId != null) ) : q; .

2. @AluanHaddad, поскольку EF и LINQ для SQL помечены, ?. не будет поддерживаться.

3. @NetMage да, но я не использую его внутри дерева выражений.

4. Но оригинальный плакат — q это IQueryable то, что строит Expression дерево, отсюда и теги для EF и LINQ для SQL.

Ответ №1:

Итак, если входные условия являются:

  • matchingRecords не равно нулю;
  • matchingRecords не пустой (содержит элементы, .Count > 0 );
  • if-else использование не допускается;

можно ли это сделать через ternary ?

 var list = matchingRecords?.Count > 0 ?
           q.Where(s => !matchingRecords.Contains(s.Id) amp;amp; s.SecId != null).ToList()
           : new List<Record>();
 

matchingRecords? проверяет наличие null и .Count после проверки на «не пусто». If-else заменен на троичный, который будет фильтровать сбор с использованием Where или возвращать new List<Record> в else случае.

Образец:

 class Program
{
    private static List<int> matchingRecords; // It is null, we "forget" to initialize it

    static void Main(string[] args)
    {
        var list = new List<Record>() 
        {
            new Record { Id = 0, SecId ="Some SeqId" },
            new Record { Id = 1, SecId = null },
            new Record { Id = 2, SecId = "Another SeqId" },
        };

        var filteredRecords = FilterRecords(list);
    }

    static IEnumerable<Record> FilterRecords(IEnumerable<Record> q)
    {
        return matchingRecords?.Count > 0 ? // Checking for not null and not empty (if case)
               q.Where(s => !matchingRecords.Contains(s.Id) amp;amp; s.SecId != null)
               : q; // else case
    }
}

public class Record
{
    public int Id { get; set; }
    public string SecId { get; set; }
}
 

Не уверен, что правильно воспроизвел вашу ситуацию, поэтому поправьте меня, если что-то не так.

Ответ №2:

  q = q.Where(s => (matchingRecords != null amp;amp; matchingRecords.Count > 0 amp;amp; 
                !matchingRecords.Contains(s.Id))
                || (s.SecId != null)
             );
 

Условие совпадения записей != null amp;amp; Совпадение записей.Количество > 0 обеспечит !совпадающие записи.Содержит(s.Id) выполняется только в том случае, если в совпадающих записях есть хотя бы 1 запись