正如问题所示,我想从选择查询中删除列,其中该列为空。
var query = from a in ...
select new
{
A =(decimal?)null,
B =(decimal?)null,
C = a.Amount1
};
var query2 = from b in ...
select new
{
A = b.Amount2,
B = b.Amount3,
C = (decimal?)null
};
var query3 = query.Concat(query2);
输出:
query3=[0]{A=null, B=null, C=100.00}
[1]{A=100.00, B=50.25, C=null}
预期结果:
query3=[0]{C=100.00}
[1]{A=100.00, B=50.25}
答案 0 :(得分:0)
LINQ查询通常输出公共类型的对象,因此每个对象必须具有相同的基本类型(以及相关的列。连接不同类型的对象的唯一方法是转换它们到object
:
var query = from a in ...
select new
{
C = a.Amount1
};
var query2 = from b in ...
select new
{
A = b.Amount2,
B = b.Amount3,
};
var query3 = query.Cast<object>().Concat(query2.Cast<object>());
但由于他们是匿名的,因此您必须使用dynamic
来访问它们;因为您赢了;所以您可以退回原始类型,这样您就会结束用这样的东西:
Console.WriteLine(((dynamic)(query3[0])).C);
Console.WriteLine(((dynamic)(query3[1])).A);
或充其量:
dynamic list = query3.ToList();
Console.WriteLine(list[0].C);
Console.WriteLine(list[1].A);
但无论如何你都会失去编译时类型的安全性。
答案 1 :(得分:0)
你不能这样做。结果集必须包含相同类型的项目,即使字段为空,它们仍然必须在那里。
您无法在用户界面中显示它们,但具体操作方式取决于用户界面。
答案 2 :(得分:0)
你做不到。一个类有一组预定义的字段(不是说ExpandoObject
,它有一些编译器技巧)。对于您使用的匿名类型,这是相同的。
您不能只隐藏或删除未填充的字段。如果您遍历实例并尝试检索item.C
,该值为null并因此被删除,该怎么办?这通常会给你一个编译器错误。 .NET如何解决这个问题?
你可以做的唯一另一件事就是在列表中放入两种不同的类型(一个对象列表,所以无类型),在我看来这是一个非常糟糕的主意。保持这样。您可以添加一个类型为行的指示符,以便能够轻松地进行测试。
所以:
select new
{
Type = "A", // or "B"
A =(decimal?)null,
B =(decimal?)null,
C = a.Amount1
};