Implicit convert List <int?> To List <int>

Я использую Linq для Entities.

Имейте сущность "Заказ", которая имеет столбец с нулевым значением "SplOrderID".

Я запрашиваю список заказов как

List<int> lst = Orders.where(u=> u.SplOrderID != null).Select(u => u.SplOrderID);

Я понимаю, что это потому, что SplOrderID является столбцом с возможностью NULL, и поэтому метод select возвращает nullable int.

Я просто ожидаю, что LINQ будет немного умнее.

Как я должен справиться с этим?

Ответы

Ответ 1

Как вы выбираете свойство, просто получите значение nullable:

List<int> lst =
  Orders.Where(u => u.SplOrderID != null)
  .Select(u => u.SplOrderID.Value)
  .ToList();

Ответ 2

LINQ

var lst = (from t in Orders
           where t.SplOrderID.HasValue
           select new Order
           {
             SplOrderID = t.SplOrderID
           }).Select(c => c.SplOrderID.Value).ToList();

или

   var lst = (from t in Orders
               where t.SplOrderID.HasValue
               select t.SplOrderID.Value).ToList();

Ответ 3

Полезный помощник/метод расширения:

Обычно я использую метод вспомогательных расширений для заданий, упомянутых в других ответах:

public static class IEnumerableExtensions
{
    public static IEnumerable<TKey> GetNonNull<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey?> keySelector) 
        where TKey : struct
    {
        return source.Select(keySelector)
            .Where(x => x.HasValue)
            .Select(x => x.Value);
    }

    // the two following are not needed for your example, but are handy shortcuts to be able to write : 
    // myListOfThings.GetNonNull()
    // whether myListOfThings is List<SomeClass> or List<int?> etc...
    public static IEnumerable<T> GetNonNull<T>(this IEnumerable<T?> source) where T : struct
    {
        return GetNonNull(source, x => x);
    }

    public static IEnumerable<T> GetNonNull<T>(this IEnumerable<T> source) where T : class
    {
        return GetNonNull(source, x => x);
    }

}

Использование в вашем случае:

// will get all non-null SplOrderId in your Orders list, 
// and you can use similar syntax for any property of any object !

List<int> lst = Orders.GetNonNull(u => u.SplOrderID);

Для читателей, которые не хотят просто игнорировать нулевые значения при преобразовании

Стоит упомянуть о потенциальном использовании GetValueOrDefault(defaultValue), но, возможно, вы хотите сохранить свои исходные значения NULL, но преобразовать их в какое-то значение по умолчанию /sentinel. (задан как параметр defaultValue):

В вашем примере:

// this will convert all null values to 0 (the default(int) value)
List<int> lst =
     Orders.Select(u => u.GetValueOrDefault())
     .ToList();

// but you can use your own custom default value
const int DefaultValue = -1;
List<int> lst =
     Orders.Select(u => u.GetValueOrDefault(DefaultValue))
     .ToList();