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

gan*_*gan 4 .net c# linq

我有 2 个 var/objects,通过这两个函数检索:

private IQueryable<Project> SelectAll_1(...)
{
    return query;
}
Run Code Online (Sandbox Code Playgroud)

类项目是:

private int ID;
private string col1;
private string col2;
private string col3;
Run Code Online (Sandbox Code Playgroud)

另一个:

private IQueryable<Project_test> SelectAll_2(...)
{
    return query;
}
Run Code Online (Sandbox Code Playgroud)

其中 POCO 是:

private string ID_inString;
private string col1;
private string col2;
private string col3;
Run Code Online (Sandbox Code Playgroud)

我需要对他们两个进行联合,

var P2 = SelectAll_2(...);
var P1 = SelectAll_1(...);

var P3 = P2.Union(P1);
Run Code Online (Sandbox Code Playgroud)

但我收到一个错误,提到:

无法从用法推断方法“System.Linq.Queryable.Union(System.Linq.IQueryable, System.Linq.Expressions.Expression>)”的类型参数。尝试明确指定类型参数。

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

Jon*_*eet 5

你不能联合两种不同的类型,除非一种继承自另一种(例如,你可能会找到IEnumerable<object>and的联合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);
Run Code Online (Sandbox Code Playgroud)

或者您可以只使用现有类型之一:

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);
Run Code Online (Sandbox Code Playgroud)

这些中哪一个是更好的主意并不是很明显 - 但如果可能的话,我会回去尝试调和这两种类型,在这一点上无论如何你都没有问题。