如何循环遍历列表中匿名类型的属性
How to loop through the properties of anonymous type in a list
如果我有以下 LINQ 查询:
var outstandingDataTotalData = from t1 in dtTotal.AsEnumerable()
join t2 in dtOutstandingData.AsEnumerable() on
new
{
priv_code = t1["priv_code"],
pri_ded = t1["pri_ded"].ToString().Trim()
} equals
new
{
priv_code = t2["priv_code"],
pri_ded = t2["pri_ded"].ToString().Trim()
}
into ps
from t2 in ps.DefaultIfEmpty()
select new
{
adjustment_value = t2 == null ? string.Empty : t2["adjustment_value"].ToString(),
amount_outstanding = t2 == null ? string.Empty : t2["amount_outstanding"].ToString(),
amount_outstanding_priv = t2 == null ? string.Empty : t2["amount_outstanding_priv"].ToString(),
amount_outstanding_ded = t2 == null ? string.Empty : t2["amount_outstanding_ded"].ToString(),
diff_outstanding = t2 == null ? string.Empty : t2["diff_outstanding"].ToString(),
exchange_rate = t2 == null ? string.Empty : t2["exchange_rate"].ToString(),
SalYear = t2 == null ? string.Empty : t2["sal_year"].ToString(),
SalMonth = t2 == null ? string.Empty : t2["sal_mon"].ToString()
};
现在outstandingDataTotalData
是一个匿名类型的列表。我有以下 class:
public class AdjustmentTotal
{
public string SalYear { get; set; }
public string SalMonth { get; set; }
public string Value { get; set; }
}
如何循环遍历 outstandingDataTotalData
属性来填充 List<AdjustmentTotal>
,如下例:
如果outstandingDataTotalData
的结果集=
[0]{ adjustment_value = "100.00", amount_outstanding = "80.00", amount_outstanding_priv = "60.00", amount_outstanding_ded = "30.52", diff_outstanding = "0.36", exchange_rate = "", SalYear = "2018", SalMonth = "1" }
[1]{ adjustment_value = "1500.00", amount_outstanding = "5040.00", amount_outstanding_priv = "", amount_outstanding_ded = "", diff_outstanding = "0.36", exchange_rate = "", SalYear = "2018", SalMonth = "1" }
我想要List<AdjustmentTotal>
的结果集为:
2018 1 100.00
2018 1 1500.00
2018 1 80.00
2018 1 5040.00
2018 1 60.00
2018 1
2018 1 30.52
2018 1
2018 1 0.36
2018 1 0.36
2018 1
2018 1
outstandingDataTotalData.Select(s => new AdjustmentTotal {
SalYear = s.SalYear,
SalMonth = s.SalMonth,
Value = s.adjustment_value
}).ToList();
让您的生活更轻松,不要提取到单独的属性。将提取物作为数组:
select new {
someArray = new[]{
t2["adjustment_value"].ToString(),
t2["amount_outstanding"].ToString(),
t2["amount_outstanding_priv"].ToString(),
t2["amount_outstanding_ded"].ToString(),
...
},
SalYear = ...,
}
所以你最终得到一个具有 3 个属性的对象,两个字符串 SalXxx 和一个字符串数组(其他值)。字符串数组意味着您可以使用 LINQ SelectMany 将其展平。您将在 msdn 示例中看到他们拥有宠物列表的所有者(宠物数量可变但您的值是固定数量)并且在 selectmany 之后它被扁平化为所有者重复并且只有一只宠物的列表。您的小写值是宠物,SalXxx 值是主人
一旦你得到一个有效的查询,你实际上可以将它集成到第一个查询中..
很抱歉没有发布完整的示例(为了清楚起见,我跳过了空检查)- 代码很难在手机上使用
编辑:
因此,您说您希望结果按特定顺序排列。 Select 和 Select 许多都有一个版本,它们会给出项目的索引,我们可以使用它.. 因为你基本上想要这些对象:
var obj = new [] {
new { SalYear = 2018, SalMonth = 1, C = new[] { "av1", "ao1", "aop1", "aod1" } },
new { SalYear = 2018, SalMonth = 2, C = new[] { "av2", "ao2", "aop2", "aod2" } }
};
像av1, av2, ao1, ao2..
所以我们想先按内部数组的索引对结果进行排序,然后按外部数组的索引
我们使用 SelectMany 来挖掘内部数组,然后对于内部数组中的每个项目,我们创建一个包含数据 和 的新对象索引(内部和外部):
obj.SelectMany((theOuter, outerIdx) =>
theOuter.C.Select((theInner, innerIdx) =>
new {
SalYear = theOuter.SalYear,
SalMonth = theOuter.SalMonth,
DataItem = theInner,
OuterIdx = outerIdx,
InnerIdx = innerIdx
}
)
).OrderBy(newObj => newObj.InnerIdx).ThenBy(newObj => newObj.OuterIdx)
您可能会发现您不需要 ThenBy;按 InnerIdx 排序将保持平局(我列表中的每个 InnerIdx 都表示两次 - 有两个 innerIdx = 0 等)并且 linq 中的东西排序到它们不能再进一步 - 因为它们已经按 OuterIdx 排序(当他们去进入查询)他们应该在绑定到 InnerIdx 之后保持按 OuterIdx 排序。如果这有意义的话。腰带和背带!
用他:
class Program
{
static void Main(string[] args)
{
List<AdjustmentTotal> totals = new List<AdjustmentTotal>();
for (int i = 0; i < (int)VALUE.END; i++)
{
foreach (var data in outstandingDataTotalData)
{
AdjustmentTotal total = new AdjustmentTotal();
totals.Add(total);
total.SalMonth = data.SalMonth;
total.SalYear = data.SalYear;
total._Type = (VALUE)i;
switch ((VALUE)i)
{
case VALUE.adjustment_value :
total.Value = data.adjustment_value;
break;
case VALUE.amount_outstanding:
total.Value = data.amount_outstanding;
break;
case VALUE.amount_outstanding_ded:
total.Value = data.mount_outstanding_ded;
break;
case VALUE.amount_outstanding_priv:
total.Value = data.amount_outstanding_priv;
break;
case VALUE.diff_outstanding:
total.Value = data.diff_outstanding;
break;
case VALUE.exchange_rate:
total.Value = data.exchange_rate;
break;
}
}
}
}
}
public enum VALUE
{
adjustment_value = 0,
amount_outstanding = 1,
amount_outstanding_priv = 2,
amount_outstanding_ded = 3,
diff_outstanding = 4,
exchange_rate = 5,
END = 6
}
public class AdjustmentTotal
{
public string SalYear { get; set; }
public string SalMonth { get; set; }
public string Value { get; set; }
public VALUE _Type { get; set; }
}
如果我有以下 LINQ 查询:
var outstandingDataTotalData = from t1 in dtTotal.AsEnumerable()
join t2 in dtOutstandingData.AsEnumerable() on
new
{
priv_code = t1["priv_code"],
pri_ded = t1["pri_ded"].ToString().Trim()
} equals
new
{
priv_code = t2["priv_code"],
pri_ded = t2["pri_ded"].ToString().Trim()
}
into ps
from t2 in ps.DefaultIfEmpty()
select new
{
adjustment_value = t2 == null ? string.Empty : t2["adjustment_value"].ToString(),
amount_outstanding = t2 == null ? string.Empty : t2["amount_outstanding"].ToString(),
amount_outstanding_priv = t2 == null ? string.Empty : t2["amount_outstanding_priv"].ToString(),
amount_outstanding_ded = t2 == null ? string.Empty : t2["amount_outstanding_ded"].ToString(),
diff_outstanding = t2 == null ? string.Empty : t2["diff_outstanding"].ToString(),
exchange_rate = t2 == null ? string.Empty : t2["exchange_rate"].ToString(),
SalYear = t2 == null ? string.Empty : t2["sal_year"].ToString(),
SalMonth = t2 == null ? string.Empty : t2["sal_mon"].ToString()
};
现在outstandingDataTotalData
是一个匿名类型的列表。我有以下 class:
public class AdjustmentTotal
{
public string SalYear { get; set; }
public string SalMonth { get; set; }
public string Value { get; set; }
}
如何循环遍历 outstandingDataTotalData
属性来填充 List<AdjustmentTotal>
,如下例:
如果outstandingDataTotalData
的结果集=
[0]{ adjustment_value = "100.00", amount_outstanding = "80.00", amount_outstanding_priv = "60.00", amount_outstanding_ded = "30.52", diff_outstanding = "0.36", exchange_rate = "", SalYear = "2018", SalMonth = "1" }
[1]{ adjustment_value = "1500.00", amount_outstanding = "5040.00", amount_outstanding_priv = "", amount_outstanding_ded = "", diff_outstanding = "0.36", exchange_rate = "", SalYear = "2018", SalMonth = "1" }
我想要List<AdjustmentTotal>
的结果集为:
2018 1 100.00
2018 1 1500.00
2018 1 80.00
2018 1 5040.00
2018 1 60.00
2018 1
2018 1 30.52
2018 1
2018 1 0.36
2018 1 0.36
2018 1
2018 1
outstandingDataTotalData.Select(s => new AdjustmentTotal {
SalYear = s.SalYear,
SalMonth = s.SalMonth,
Value = s.adjustment_value
}).ToList();
让您的生活更轻松,不要提取到单独的属性。将提取物作为数组:
select new {
someArray = new[]{
t2["adjustment_value"].ToString(),
t2["amount_outstanding"].ToString(),
t2["amount_outstanding_priv"].ToString(),
t2["amount_outstanding_ded"].ToString(),
...
},
SalYear = ...,
}
所以你最终得到一个具有 3 个属性的对象,两个字符串 SalXxx 和一个字符串数组(其他值)。字符串数组意味着您可以使用 LINQ SelectMany 将其展平。您将在 msdn 示例中看到他们拥有宠物列表的所有者(宠物数量可变但您的值是固定数量)并且在 selectmany 之后它被扁平化为所有者重复并且只有一只宠物的列表。您的小写值是宠物,SalXxx 值是主人
一旦你得到一个有效的查询,你实际上可以将它集成到第一个查询中..
很抱歉没有发布完整的示例(为了清楚起见,我跳过了空检查)- 代码很难在手机上使用
编辑:
因此,您说您希望结果按特定顺序排列。 Select 和 Select 许多都有一个版本,它们会给出项目的索引,我们可以使用它.. 因为你基本上想要这些对象:
var obj = new [] {
new { SalYear = 2018, SalMonth = 1, C = new[] { "av1", "ao1", "aop1", "aod1" } },
new { SalYear = 2018, SalMonth = 2, C = new[] { "av2", "ao2", "aop2", "aod2" } }
};
像av1, av2, ao1, ao2..
所以我们想先按内部数组的索引对结果进行排序,然后按外部数组的索引
我们使用 SelectMany 来挖掘内部数组,然后对于内部数组中的每个项目,我们创建一个包含数据 和 的新对象索引(内部和外部):
obj.SelectMany((theOuter, outerIdx) =>
theOuter.C.Select((theInner, innerIdx) =>
new {
SalYear = theOuter.SalYear,
SalMonth = theOuter.SalMonth,
DataItem = theInner,
OuterIdx = outerIdx,
InnerIdx = innerIdx
}
)
).OrderBy(newObj => newObj.InnerIdx).ThenBy(newObj => newObj.OuterIdx)
您可能会发现您不需要 ThenBy;按 InnerIdx 排序将保持平局(我列表中的每个 InnerIdx 都表示两次 - 有两个 innerIdx = 0 等)并且 linq 中的东西排序到它们不能再进一步 - 因为它们已经按 OuterIdx 排序(当他们去进入查询)他们应该在绑定到 InnerIdx 之后保持按 OuterIdx 排序。如果这有意义的话。腰带和背带!
用他:
class Program
{
static void Main(string[] args)
{
List<AdjustmentTotal> totals = new List<AdjustmentTotal>();
for (int i = 0; i < (int)VALUE.END; i++)
{
foreach (var data in outstandingDataTotalData)
{
AdjustmentTotal total = new AdjustmentTotal();
totals.Add(total);
total.SalMonth = data.SalMonth;
total.SalYear = data.SalYear;
total._Type = (VALUE)i;
switch ((VALUE)i)
{
case VALUE.adjustment_value :
total.Value = data.adjustment_value;
break;
case VALUE.amount_outstanding:
total.Value = data.amount_outstanding;
break;
case VALUE.amount_outstanding_ded:
total.Value = data.mount_outstanding_ded;
break;
case VALUE.amount_outstanding_priv:
total.Value = data.amount_outstanding_priv;
break;
case VALUE.diff_outstanding:
total.Value = data.diff_outstanding;
break;
case VALUE.exchange_rate:
total.Value = data.exchange_rate;
break;
}
}
}
}
}
public enum VALUE
{
adjustment_value = 0,
amount_outstanding = 1,
amount_outstanding_priv = 2,
amount_outstanding_ded = 3,
diff_outstanding = 4,
exchange_rate = 5,
END = 6
}
public class AdjustmentTotal
{
public string SalYear { get; set; }
public string SalMonth { get; set; }
public string Value { get; set; }
public VALUE _Type { get; set; }
}