用匿名类型连接两个IQueryables

本文关键字:两个 IQueryables 类型 连接 | 更新日期: 2023-09-27 18:10:49

我已经纠结了一段时间了,现在看起来似乎不太可能了。

我想要Concat()两个IQueryable,然后将结果作为单个查询执行。我尝试这样做:

var query = from x in ...
select new
{
    A = ...
    B = ...
    C = ...
};
var query2 = from y in ...
select new
{
    A = ...
    B = ...
    C = ...
};
var query3 = query.Concat(query2);

然而,最后一行给出了以下错误:

"来。IQueryable'不包含'Concat'的定义和最佳扩展方法重载'System.Linq. parallelenumerable .Concat(System.Linq. parallelenumerable .Concat(System.Linq. linq . parallelenumerable) '。ParallelQuery, System.Collections.Generic.IEnumerable)'有一些无效的参数

它似乎期待参数的IEnumerable。还有别的办法吗?

看起来我可以解决这两个查询IEnumerable s,然后Concat()他们。但是创建单个查询会更有效,而且看起来应该是可能的。

用匿名类型连接两个IQueryables

正如您之前在评论中所说的,似乎这两个查询返回不同的对象:

查询1(根据注释):

f__AnonymousTypee<Leo.Domain.FileItem,Leo.Domain.Employ‌​ee,int,string,string>

Query2是

f__AnonymousTypee<Leo.Domain.FileItem,L‌​eo.Domain.Employee,int?,string,string>

这就是为什么Concat给你一个错误消息抱怨无效参数

匿名对象将与其他匿名对象具有相同的属性名称和类型,且声明顺序完全相同。

假设queryquery2都来自相同的上下文中,如果它们是相同类型的查询,您应该能够将它们组合在一起。

你的注释表明两者都不是同一类型。

query返回类型为Anon<FileItem, Employee, int, string, string>的对象
query2返回Anon<FileItem, Employee, int?, string, string>类型的对象。

你不能合并这两个,因为它们是不同的类型。您需要确保两个查询返回相同类型的对象。

var query = from x in ...
    select new
    {
        A = (FileItem)...
        B = (Employee)...
        C = (int)...
        ...
    };
var query2 = from y in ...
    select new
    {
        A = (FileItem)...
        B = (Employee)...
        C = (int)...
        ...
    };

IDE确定的query和query2是不同的类型,而IEnumerableConcat()扩展方法期望两个相同的类型(IEnumerable)。三个TSource必须相同

string[] strA = {"123", "234", "345"};
int[] intA = { 1, 2, 3 };
var query = from s in strA
            select s;
var query2 = from i in strA // intA
                select i;
var query3 = query.Concat(query2);

在VS中取消注释"//intA",你会看到不同。

您是否缺少任何名称空间?通常我将。net项目属性标记为vs 2010的。net 4.0。我不使用。net 4.0客户端配置文件。

请确保A, B和C的类型在两个查询匿名类型中都是匹配的。另外,A, B和C的顺序也应该在两个查询中匹配。

下面的例子很有魅力。

namespace Test
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    internal class Employee
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public double Salary { get; set; }
        public string Address { get; set; }
    }
    internal class Program
    {
        private static List<Employee> employees = new List<Employee>();
        private static void BuildList()
        {
            employees.AddRange(
                new Employee[]
                    {
                        new Employee() {Name = "Tom", Age = 22, Address = "sample1", Salary = 10000},
                        new Employee() {Name = "Mithun", Age = 27, Address = "sample1", Salary = 20000},
                        new Employee() {Name = "Jasubhai", Age = 24, Address = "sample1", Salary = 12000},
                        new Employee() {Name = "Vinod", Age = 34, Address = "sample1", Salary = 30000},
                        new Employee() {Name = "Iqbal", Age = 52, Address = "sample1", Salary = 50000},
                        new Employee() {Name = "Gurpreet", Age = 22, Address = "sample1", Salary = 10000},
                    }
                );
        }
        private static void Main(string[] args)
        {
            BuildList();
            var query = from employee in employees
                        where employee.Age < 27
                        select new
                            {
                                A = employee.Name,
                                B = employee.Age,
                                C = employee.Salary
                            };

            var query2 = from employee in employees
                         where employee.Age > 27
                         select new
                             {
                                 A = employee.Name,
                                 B = employee.Age,
                                 C = employee.Salary
                             };
            var result = query.Concat(query2);
            foreach (dynamic item in result.ToArray())
            {
                Console.WriteLine("Name = {0}, Age = {1}, Salary = {2}", item.A, item.B, item.C);
            }
        }

    }
}