用匿名类型连接两个 IQueryable?

问题描述 投票:0回答:4

我已经为此苦苦挣扎了一段时间,现在看来这似乎是不可能的。

我想

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()
它们。但创建单个查询会更有效,而且看起来这应该是可能的。

c# linq entity-framework iqueryable
4个回答
8
投票

你不能。

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

查询1(根据评论):

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

查询2是

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

这就是为什么

Concat
会向您提供一条错误消息,抱怨参数无效。


3
投票

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

假设

query
query2
来自相同的上下文,您应该能够将两者结合起来,前提是它们是等效类型的查询。

您的评论表明两者都不是同一类型。

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)...
        ...
    };

1
投票

IDE 确定 query 和 query2 属于不同类型,而 IEnumerable Concat() 扩展方法需要两个相同的类型 (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”,你就会看到差异。


-1
投票

您是否缺少任何名称空间?通常,我将 .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);
            }
        }


    }
}
© www.soinside.com 2019 - 2024. All rights reserved.