我有2个var /对象,通过这两个函数检索:
private IQueryable<Project> SelectAll_1(...)
{
return query;
}
类项目是:
private int ID;
private string col1;
private string col2;
private string col3;
和另一个:
private IQueryable<Project_test> SelectAll_2(...)
{
return query;
}
其中POCO是:
private string ID_inString;
private string col1;
private string col2;
private string col3;
我需要对它们进行联合,
var P2 = SelectAll_2(...);
var P1 = SelectAll_1(...);
var P3 = P2.Union(P1);
但我得到一个错误,提到:
无法从用法中推断出方法'System.Linq.Queryable.Union(System.Linq.IQueryable,System.Linq.Expressions.Expression&gt;)'的类型参数。尝试明确指定类型参数。
我看到有些人通过'匿名类型解决它,但我不确定它是如何工作的。任何人都有任何想法?
答案 0 :(得分:4)
你不能联合两种不同的类型,除非一个继承另一个(例如,你可以可能找到IEnumerable<object>
和IEnumerable<string>
的联合,尽管很少有用)。
现在在你的情况下,如果各种属性具有相同的含义,它听起来像Project
和Project_test
应该是一种类型。目前ID属性有不同的类型 - 但这是真的必要还是可取的?如果它们都是具有相同范围的标识符,则将它们存储在相同的表示中是有意义的。如果属性没有具有相同的含义,则根本不应在它们之间形成联合。如果他们做具有相同的含义,您应该尝试使两个序列使用相同的类型。
你可以使用匿名类型,这样:
var projectedP1 = P1.Select(x => new { x.ID, x.col1, x.col2, x.col3 });
var projectedP2 = P2.Select(x => new { ID = int.Parse(x.ID_inString),
x.col1, x.col2, x.col3 });
var union = projectedP1.Union(projectedP2);
或者你可以使用现有的一种类型:
var projectedP1 = P1.Select(x => new Project_test {
ID_inString = x.ID.ToString(),
col1 = x.col1,
col2 = x.col2,
col3 = x.col3 });
var union = projectedP1.Union(P2);
这些并不是一个更好的想法 - 但是如果可能的话,我会回到尝试来调和这两种类型,此时你没有任何问题。
答案 1 :(得分:1)
问题在于P2
是IQueryable<Project>
而P3
是IQueryable<Project_test>
,您不能将它们合并为一个序列,因为它们的类型不同。
你需要做的是将它们都投射到一个普通类型的中并进行Select()
调用,其中据我所知必须是一个命名类型根据Jon Skeet可以用匿名类型完成。定义匿名类型的初始化块必须具有相同数量的成员,具有相同的名称,顺序相同,并且相同的类型必须被视为一种类型。要使用Select()
投影类型,您还需要使属性公共,以便linq方法可以访问。