Concat有两个匿名类型的IQueryables?

时间:2014-07-01 01:31:28

标签: c# linq entity-framework iqueryable

我已经和它摔跤了一段时间,看起来可能不太可能。

我想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);

但是,最后一行给出了以下错误:

  

' System.Linq.IQueryable'不包含' Concat'的定义和最好的扩展方法重载' System.Linq.ParallelEnumerable.Concat(System.Linq.ParallelQuery,System.Collections.Generic.IEnumerable)'有一些无效的论点

它似乎期待IEnumerable这个论点。有没有办法解决这个问题?

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

4 个答案:

答案 0 :(得分:5)

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

查询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给你一个抱怨无效参数的错误信息的原因。

答案 1 :(得分:3)

匿名对象将是具有相同属性名称和类型的其他匿名对象的等效类型。

假设来自相同上下文的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)...
        ...
    };

答案 2 :(得分:1)

IDE确定的查询和查询2具有不同的类型,而IEnumerable&lt; TSource&gt; Concat&lt; TSource&gt;()扩展方法需要两个相同的类型(IEnumerable&lt; TSource&gt;)。三个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”,你会看到差异。

答案 3 :(得分:0)

您是否遗漏了任何名称空间?通常我将我的.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);
            }
        }


    }
}