需要在Union()中通过匿名类型显式转换

时间:2011-07-30 17:46:04

标签: c# .net linq

我有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;)'的类型参数。尝试明确指定类型参数。

我看到有些人通过'匿名类型解决它,但我不确定它是如何工作的。任何人都有任何想法?

2 个答案:

答案 0 :(得分:4)

你不能联合两种不同的类型,除非一个继承另一个(例如,你可以可能找到IEnumerable<object>IEnumerable<string>的联合,尽管很少有用)。

现在在你的情况下,如果各种属性具有相同的含义,它听起来像ProjectProject_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)

问题在于P2IQueryable<Project>P3IQueryable<Project_test>,您不能将它们合并为一个序列,因为它们的类型不同。

你需要做的是将它们都投射到一个普通类型的中并进行Select()调用,其中据我所知必须是一个命名类型根据Jon Skeet可以用匿名类型完成。定义匿名类型的初始化块必须具有相同数量的成员,具有相同的名称,顺序相同,并且相同的类型必须被视为一种类型。要使用Select()投影类型,您还需要使属性公共,以便linq方法可以访问。

相关问题