Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何合并两个LINQ查询,但第二个查询需要更多字段_C#_Linq_Entity Framework - Fatal编程技术网

C# 如何合并两个LINQ查询,但第二个查询需要更多字段

C# 如何合并两个LINQ查询,但第二个查询需要更多字段,c#,linq,entity-framework,C#,Linq,Entity Framework,我需要在两个LINQ查询之间进行联合,但是第二个查询需要比第一个查询有更多的字段。我怎么做 例如: public static void Dummy() { var query1 = this.Db.Table1.Select(s => new MyObject() { A = s.Field1, B = s.Field2 }); var query2 = this.Db.Table2.Select(s => new MyObject() { A = s.Field

我需要在两个LINQ查询之间进行联合,但是第二个查询需要比第一个查询有更多的字段。我怎么做

例如:

public static void Dummy()
{
    var query1 = this.Db.Table1.Select(s => new MyObject() { A = s.Field1, B = s.Field2 });

    var query2 = this.Db.Table2.Select(s => new MyObject() { A = s.Field1, B = s.Field2, C = s.Field3 });

    var result = query1.Union(query2);
}
调用result.ToList()时,发生以下错误:

“MyObject”类型出现在两个结构不兼容的类型中 在单个LINQ到实体查询中进行初始化。类型可以是 在同一查询中的两个位置初始化,但仅当 属性在两个位置都设置,并且这些属性在 同样的顺序

我如何解决这个问题


Obs.:我无法将
字段3
放入
查询1
(我无法访问查询1,因为我无法更改它)

您不必在第一次查询中放入
字段3
,但
Union
要求相同的列数和顺序。为第三列/字段
C
指定虚拟值,如:

var query1 = this.Db.Table1.Select(s => new MyObject() 
                        { A = s.Field1, B = s.Field2 , C= ""});
var newQuery = query1.Select(s=> new MyObject() 
                            { A = A, B = B , C= ""}); 
分配
C
任何
Field3
的默认值,对于参考类型可以是
null
,对于数字等可以是
0

如果您没有访问权限,请修改
query1
,然后使用
query1
创建一个新查询,如:

var query1 = this.Db.Table1.Select(s => new MyObject() 
                        { A = s.Field1, B = s.Field2 , C= ""});
var newQuery = query1.Select(s=> new MyObject() 
                            { A = A, B = B , C= ""}); 
然后在
Union

var result = newQuery.Union(query2);

事实上,你不能。只能合并两个具有相同结构的集合。但是,如果您不介意修改
查询1
,请执行以下操作:

var query1 = this.Db.Table1.Select(s => new MyObject() 
                                        { A = s.Field1, B = s.Field2, C = null });

这将允许它们正确地合并,因为它们具有相同的结构。

因为query1中的记录永远不会有属性“C”,而query2中的所有记录都会有属性“C”,所以query1中的记录不太可能等同于query2中的记录。在Concat上使用Union的唯一原因是删除重复项,因为您不能有任何重复项,所以您应该使用Concat而不是Union

public static void Dummy()
{
    var query1 = this.Db.Table1.Select(s => new MyObject() { A = s.Field1, B = s.Field2 });

    var query2 = this.Db.Table2.Select(s => new MyObject() { A = s.Field1, B = s.Field2, C = s.Field3 });

    var result = query1.ToList().Concat(query2);
}
也有例外,例如,如果您有一个自定义IEqualityComparer for MyObject,它忽略了“C”属性,或者“C”属性的默认值可能存在于表2的记录中,并且您希望删除重复项,或者如果query1或query2中可能存在重复项,并且您希望删除它们,那么您仍然可以使用Concat,但是你需要在Concat之前使用Distinct

编辑以强制query1在通过.ToList()连接之前实现

使用LinqPad进行了双重检查,以下可执行文件没有问题,使用的数据源的类别和城市表都是完全不同的模式:

void Main()
{
    var query1 = Categories.Select(s => new MyObject { A = s.id, B = s.name });

    var query2 = Cities.Select(s =>  new MyObject { A = s.id, B = s.city_name, C = s.location });

    var result = query1.ToList().Concat(query2);
    result.Dump();
}
public class MyObject
{
    public int A {get;set;}
    public string B {get;set;}
    public object C {get;set;}
}

你可以这样做:

public static void Dummy()
{
    var query1 = this.Db.Table1.Select(s => new MyObject() { A = s.Field1, B = s.Field2 });

    var query1modified = this.Db.Table2.Select(s => new MyObjectUnion() { A = s.Field1, B = s.Field2, C = null });

    var query2 = this.Db.Table2.Select(s => new MyObjectUnion() { A = s.Field1, B = s.Field2, C = s.Field3 });

    var result = query1modified.Union(query2);
}
创建与MyObject不同的对象

class MyObjectUnion : MyObject{
}
因此,方法如下:

public static void Dummy()
{
    var query1 = this.Db.Table1.Select(s => new MyObject() { A = s.Field1, B = s.Field2 });

    var query1modified = this.Db.Table2.Select(s => new MyObjectUnion() { A = s.Field1, B = s.Field2, C = null });

    var query2 = this.Db.Table2.Select(s => new MyObjectUnion() { A = s.Field1, B = s.Field2, C = s.Field3 });

    var result = query1modified.Union(query2);
}

它可以工作

错误消息是不言自明的!如果您已经在SQL Server等中使用了
Union
,那么很容易理解它的意思。我无法更改查询1,因为我没有访问该查询的权限。@RenatoLeite,您可以在
query1
上创建一个新查询,我添加了一些新代码,尝试一下。我尝试了,但没有解决问题,错误持续存在:(@RenatoLeite取决于返回的数据的大小,以及是否需要读取所有记录。如果不需要读取所有记录(或多次读取),请将.ToList()更改为.AsEnumerable()