2015-02-03 2 views
2

Я работаю с C#, .NET4.5, EF6 (не имеет значения, действительно).По умолчаниюIfEmpty return null

Я выбрать несколько значений из БД затем .ToList() их, а затем добавить DefaultIfEmpty(new ActualFee{Net = 0, Vat = 0}), если один не существует, и я получаю null

public static ConveyancingSummaryVm ToConveyancingSummaryVm(this Tuple<IEnumerable<ActualFee>, ConveyancingAnswer, Customer> conveyancePricingAnswersAndCustomer) 
     { 
      var purchaseFees = conveyancePricingAnswersAndCustomer.Item1.Where(o => o.ConveyancingSaleType == "Purchase").ToList(); 

      if (purchaseFees.Any()) 
      { 
       var discount = purchaseFees.DefaultIfEmpty(new ActualFee{Net = 0, Vat = 0}).SingleOrDefault(o => o.Title.Contains("Discount")); 

       conveyancingSummaryVm.IsPurchaseFreehold = conveyancePricingAnswersAndCustomer.Item2.PropertyBoughtIsFreehold; 
... 

enter image description here

Я должен отсутствовать что-то очевидное здесь.

+1

скорее всего SingleOrDefault возвращает null. –

+0

См. Выше комментарий - но также, зачем использовать DefaultIfEmpty в сочетании с Any() - по-видимому, он не может быть пустым, если у вас есть «Some». – SpaceBison

+0

@ Selman22, так что вы говорите, что 'DefaultIfEmpty' не работает для' SingleOrDefault'? –

ответ

3

Нет способа для DefaultIfEmpty вернуть null в этом случае. Когда нет элемента, он возвращает экземпляр ActualFee, а Title не содержит Discount. Вот почему SingleOrDefault возвращает null.

, так что вы говорите, что DefaultIfEmpty не работает для SingleOrDefault?

Нет, DefaultEmpty работы и возвращает ожидаемый value.And затем SingleOrDefault работает на возвращаемом значении DefaultIfEmpty и возвращает нуля потому что нет никаких элементов в последовательности, которая удовлетворяет ваше состояние.

Вы можете использовать пустой оператор коалесцирующий, чтобы получить требуемое поведение:

var discount = purchaseFees.FirstOrDefault(o => o.Title.Contains("Discount")) 
       ?? new ActualFee{Net = 0, Vat = 0}; 
+0

Итак, в основном это так? 'var discount = purchaseFees.Any (o => o.Title.Contains (« Скидка »))? buyFees.Single (o => o.Title.Contains («Скидка»)): новый ActualFee {Net = 0, Vat = 0}; ' –

+0

@Liufa Я бы предпочел FirstOrDefault, и нет необходимости в Any. Я обновил свой ответ –

2

SingleOrDefault должно быть, вернулся null. Если DefaultIfEmpty вернул null, он вернул бы Object reference not set to an instance of an object. Пожалуйста, перепишите это заявление без цепочки.

0

ОП здесь: изображено другое обходное решение.

Вместо того, чтобы использовать Single(), если вы готовы «пожертвовать» чеком для его единственной записи, вы можете использовать Where() и Sum() комбо.

Я знаю, что всегда есть один или ноль.

Пример:

var feeValue = legalFees.Where(o => o.Title.Contains("Severance")); 
premiumDetails.LegalFeeNet = feeValue.Sum(o => o.Net); 
premiumDetails.LegalFeeVat = feeValue.Sum(o => o.Vat); 

, если нет записей это возвращает 0 для Net и Vat и если есть - возвращает значения.

UPDATE - Понял еще один:

legalFees.Where(o => o.Title.Contains("Severance")).Union(new ActualFee{Net = 0, Vat = 0}).First();

если Where() делает что-то вернуть, то First() будет значение, которое Contains("Severance"), если не - то First() будет то, что в Union().