这是我的第一个问题,如果出现问题,请抱歉。
我正在使用具有以下型号的应用程序:
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>
中的所有税款和它们的值的总和,我认为这是使用总和的一个组,但我不知道如何应用该组在列表内的列表中。
您能知道这是否可行,或者是否存在其他方式吗?
非常感谢您的帮助!
答案 0 :(得分:1)
您的标准尚不明确,因此,这里有一些我认为是您想要的解决方案。
使用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();
答案 1 :(得分:0)
您写道:
物品有不同的税款,但大多数物品有相同的税款
您要做的最重要的事情是定义两个税款何时相等。当它们具有相等的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>
。
通常答案不是那么困难,我想您要说的是,如果两个Taxes具有相同的TaxValue,则它们是相等的
所以您的要求如下:
要选择输入项的属性,请使用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,则它们是相等的
在这种情况下,您必须编写一个相等比较器。它们不是很困难,但是您应该记住一些事情:
考虑阅读Define Value Equality for a Type
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是诸如Dictionary,Sets之类的类和诸如Distinct()之类的函数所使用的一种优化,用于快速查找不平等。没有定义此功能的“最佳”方法。 Stack overflow: Best algorithm for GetHashCode可能会对您有所帮助。
一旦定义了类,就可以在Distinct中使用相等比较器:
// use default equality (= equal if same object)
...
.Distinct(TaxesEqualityComparer.Default)
// use your own definition of Taxes equality:
...
.Distinct(TaxesEqualityComparer.ValueComparer)