сумма и сгруппировать в списке модели внутри списка другой модели - PullRequest
0 голосов
/ 07 декабря 2018

Это мой первый вопрос, поэтому, пожалуйста, извините, если что-то выглядит не так.

Я работаю в приложении, где у меня есть следующие модели:

public class OrderDetails {
 int DetailID {get; set;}
 List<Taxes> taxes {get; set;}
}

public class Taxes {
 int TaxID {get; set;}
 decimal TaxValue {get; set;}
}

Так в кодеу меня есть List<OrderDetails>, в котором много предметов, и что предметы имеют разные налоги, но в основном предметы имеют одинаковые налоги.Мне нужно создать генерал List<Taxes>, в котором у меня будут все налоги в List<OrderDetails> и сумму их значений. Я думаю, что это группа с использованием суммы, но я не знаю, как применить группу в спискевнутри списка.

Можете ли вы знать, возможно ли это или нет, или существует другой способ сделать это?

Большое вам спасибо за вашу помощь !!

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Вы писали:

предметы облагаются разными налогами, но в основном предметы облагаются одинаковыми налогами

Самое важное для вас - определить, когда два налогаравны.Это когда они равны TaxId и TaxValue, или когда они имеют одинаковые TaxValue, или это должен быть один и тот же объект.Итак, какие из этих пяти налогов равны:

Taxes a = new Taxes {Taxid = 1, TaxValue = 3};
Taxes b = new Taxes {Taxid = 1, TaxValue = 4};
Taxes c = new Taxes {Taxid = 2, TaxValue = 4};
Taxes d = new Taxes {Taxid = 2, TaxValue = 4};
Taxes e = d;

Если ваш ответ будет: это зависит: иногда только d == e (тот же объект), иногда b == c == d == e (равный TaxValue), то вы должны предоставить средство сравнения равенства: объект, который реализует IEqualityComparer<Taxes>.

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

Итак, ваши требования следующие:

  • Ввод: последовательность OrderDetails.Каждый OrderDetail имеет DetailId и последовательность из нуля или более налогов.Каждый налог имеет TaxId и TaxValue.
  • Два налога считаются равными, если они имеют одинаковое TaxValue.
  • Запрошенный вывод: Из каждого OrderDetail DetailId и последовательности всех его уникальных налогов.

Чтобы выбрать свойства элементов ввода, используйте Enumerable.Select Для сохранениятолько уникальные выходные значения последовательности используют Enumerable.Distinct

var result = myOrderDetails               // take my sequence of OrderDetails
    .Select(orderDetail => new            // from every orderDetail in this sequence make one new object
    {                                     // with the following properties
         DetailId = orderDetail.DetailId,

         TaxValues = orderDetail.Taxes    // from all Taxes of this orderDetail,
            .Select(tax => tax.TaxValue)  // select only the TaxValues
            .Distinct(),                  // and remove duplicates

         // or if two taxValues are equal if they are the same object:
         Taxes = orderDatail.Taxes          // from all Taxes of this orderDetail
             .Distinct()                    // remove duplicates
             .Select(tax => tax.TaxValue),  // and keep only the TaxValue (optional)
    });

Если ваша идея о равенстве налогов не является такой простой, например, если вы определите равенство как:

Два налога равны, если они имеют одинаковый TaxId и равны TaxValue

В этом случае вам придется написать средство сравнения на равенство.Они не очень сложны, однако вы должны иметь в виду кое-что:

  • Что делать с нулевым значением?Если оба значения равны нулю, равны ли они?
  • Имейте в виду, что производный класс TaxValue обычно не равен самому TaxValue

Рассмотрите возможность чтения Определите равенство значенийдля типа

class TaxesEqualityComparer : EqualityComparer<TaxValue>
{

    public static readonly IEqualityComparer<TaxValue> ValueComparer
           = new TaxesEqualityComparer()

    public override bool Equals(TaxValue x, TaxValue y)
    {
        // the following lines are almost always the same:
        if (x == null) return y == null;               // true if both null
        if (y != null) return false;                   // because x not null and y is null
        if (Object.ReferenceEquals(x, y) return true;  // optimalization: same object
                                                       // no need to check the properties
         if (x.GetType() != y.GetType()) return false; // not same type

         // here start the differences of default Taxes comparison
         // when would you say that two Taxes are equal?
         return x.TaxId == y.TaxId
             && x.TaxValue == y.TaxValue;
    };

    public override int GetHashCode(x)
    {
        ...
    }
}

GetHashCode - это оптимизация, используемая такими классами, как словари, наборы, и функциями, такими как Distinct (), для быстрого поиска неравенств.Не существует «лучшего» способа определить эту функцию. Переполнение стека: лучший алгоритм для GetHashCode может помочь вам.

После того, как вы определили класс, вы можете использовать равный компаратор в Distinct:

// use default equality (= equal if same object)
...
.Distinct(TaxesEqualityComparer.Default)

// use your own definition of Taxes equality:
...
.Distinct(TaxesEqualityComparer.ValueComparer)
0 голосов
/ 07 декабря 2018

Ваши критерии не совсем ясны, поэтому вот пара решений, которые, я считаю, именно то, что вы ищете.

Используйте SelectMany, чтобы сгладить вложенные последовательности, а затем сгруппировать по TaxId, а затемпреобразуйте с помощью Select:

var result = orderDetailses.SelectMany(x => x.taxes)
            .GroupBy(x => x.TaxID)
            .Select(x => new Taxes
            {
                TaxID = x.Key,
                TaxValue = x.Sum(e => e.TaxValue)                    
            }).ToList();

или, возможно, вы ищете:

var result = orderDetailses.SelectMany(o => o.taxes.Select(t => (TaxId: t.TaxID, orderDetailses: o)))
                .GroupBy(i => i.TaxId)
                .Select(e => new Taxes
                {
                    TaxID = e.Key,
                    TaxValue = e.SelectMany(x => x.orderDetailses.taxes)
                        .Sum(a => a.TaxValue)
                }).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...