C# 按LINQ从组中以逗号分隔的值(具有定义的顺序);无法创建常量值,仅支持基元类型或枚举类型

C# 按LINQ从组中以逗号分隔的值(具有定义的顺序);无法创建常量值,仅支持基元类型或枚举类型,c#,entity-framework,linq,grouping,C#,Entity Framework,Linq,Grouping,我有以下两张桌子 Table1: Number Table2ID Count ====== ======== ===== 1 1 3 1 2 5 1 4 2 1 5 4 2 1 6 2 3 2

我有以下两张桌子

Table1:

Number     Table2ID       Count
======     ========       =====
1          1              3
1          2              5
1          4              2
1          5              4
2          1              6
2          3              2
2          2              4
2          5              3


Table2:

ID     Code     Sequence
==     ====     ========
1      AA       1
2      BB       2
3      CCC      3
4      D        4
5      EE       5

使用这些表,我希望得到以下结果:

Number     Codes
======     =====
1          AA, BB, D, EE
2          AA, BB, CCC, EE
为此,我根据编写了以下查询:

在执行此查询时,我遇到了以下例外情况,如该答案的注释中所述:

LINQ to Entities无法识别“System.String JoinSystem.String,System.String[]”方法,并且无法将此方法转换为存储表达式

为了修复此异常,我根据进行了以下更正:

修改后,我在执行查询时开始出现以下异常:

错误:无法创建“匿名类型”类型的常量值。在此上下文中仅支持基元类型或枚举类型

为了理解我在哪个select子句中遇到问题,我为每个select子句声明了一个类-因此,查询被修改为:

from tempResult in (from t1 in Table1
                    join t2 in Table2
                    on t1.Table2ID equals t2.ID
                    select new TempResult
                    {
                        Number = t1.Number,
                        Code = t2.Code,
                        Sequence = t2.Sequence
                    }).AsEnumerable()  // converted the result as enumerable 
group tempResult by tempResult.Number into groupedTempResult
select new Result
{
   Number = groupedTempResult.Key,
   Codes = string.Join(", ", groupedTempResult.OrderBy(x => x.Sequence).Select(x => x.Code))
}
在这次修改之后,我得到了以下异常:

错误:无法创建“Namespace.Name.Result”类型的常量值。在此上下文中仅支持基元类型或枚举类型

根据我的理解,最后一个select子句是发生异常的地方

我试着尽可能多地遵循以下问题的答案,从而产生了一个新版本的查询

from tempResult in (from t1 in Table1
                    join t2 in Table2
                    on t1.Table2ID equals t2.ID
                    select new TempResult
                    {
                        Number = t1.Number,
                        Code = t2.Code,
                        Sequence = t2.Sequence
                    }).AsEnumerable()
                      .GroupBy(x => x.Number)
                      .Select(x => new Result { Number = x.Key, Codes = string.Join(", ", x.OrderBy(y => y.Sequence).Select(y => y.Code)) })
select tempResult
这并没有解决前面提到的异常

在这一点上,我非常不知道如何才能得到我想要的结果

非常感谢您在这个问题上提供的任何帮助

需要注意的一点是,我必须将此查询/操作的结果与另一个查询连接起来。因此,将此查询分解为多个语句/操作不是我想要的

编辑:让我试着澄清一下我是如何实际使用这个查询的

from otherResult1 in resultFromAnotherQuery1
join result in (from tempResult in (from t1 in Table1
                                    join t2 in Table2
                                    on t1.Table2ID equals t2.ID
                                    select new TempResult
                                    {
                                        Number = t1.Number,
                                        Code = t2.Code,
                                        Sequence = t2.Sequence
                                    }).AsEnumerable()
                                      .GroupBy(x => x.Number)
                                      .Select(x => new Result { Number = x.Key, Codes = string.Join(", ", x.OrderBy(y => y.Sequence).Select(y => y.Code)) })
                select tempResult).ToList()
on otherResult1.Number equals result.Number
join otherResult2 in resultfromAnotherQuery2
on otherResult1.ColumnA equals otherResult2.ColumnB
.....
select new FinalResult
{
    .......
    Codes = result.Codes,
    .......
}

如果我跳过与result和otherResult1的连接,忽略填充FinalResult类中的Codes字段-只需使用otherResult1和otherResult2,执行查询就没有问题。但当我尝试执行此联接时,我会遇到问题中提到的异常。

简而言之:这里需要的是强制执行查询的第一部分。将.AsEnumerable切换到.ToList以强制在该点执行

再长一点:第一个查询失败,因为它无法转换字符串。请连接到SQL等效项。引入AsEnumerable并不会强制立即执行,在本例中,它只是将问题向下移动了一步。我不确定具体细节,但查看GroupBy的实现应该可以解释原因。因此,托利斯特强制执行死刑

或者你可以看看ToLookup而不是GroupBy


基于这一点,但也可以看到,也可能会对AsEnumerable和ToList之间的差异有所了解。最后,它归结为一种结构,如

来自resultFromAnotherQuery1中的q 从…上的listOfObjects中加入o。。。 选择新{} 在这里,ListoObject是介于tempResult in和最后一段代码中的列表之间的所有内容。与resultfromAnotherQuery2的连接对于答案并不重要

我希望EF的创建者能够为这个频繁发生的错误提供一个更令人满意的异常消息。比如:

EF正在尝试将整个语句[statement]转换为SQL,但本地序列“ListoObjects”只有在包含基元值时才能转换

不幸的是,创建本地序列的部分最初向实体抛出了另一个异常LINQ,但该部分无法识别该方法。。。。解决了这个问题后,您遇到了第二个异常。由于您完全专注于本地序列,并且没有得到神秘消息的帮助,因此您一直在那里寻找解决方案。但例外情况现在悄悄地转移到了整个声明中

解决方案是组合所有内容,直到从iQueryTables中选择新的FinalResult。然后添加一个numerable,然后。选择X=>newfinalResult{…},在这里你可以做EF不支持的事情

这意味着您必须挂起字符串。连接部分直到结束:

.Selectx=>newfinalResult { ....... 代码=字符串.连接,x.代码 ....... } …其中x.代码由以下内容组成

Codes=groupedTempResult.OrderByx=>x.Sequence.Selectx=>x.Code
哪个EF版本?@GertArnold:EF 6.1.3我编辑了这个问题,以显示我如何尝试使用我提供的查询。我尝试在查询中分别用.ToList替换.AsEnumerable和用ToLookup替换GroupBy,结果在每种情况下都没有变化。您可以查看更新后的问题,看看是否可以提出其他建议..AsEnumerable不强制执行,但它确实强制执行
在内存中强制执行。您的答案不正确,它基于原始问题中不完整的代码。因为我的查询没有在.Select方法中创建FinalResult类,所以我必须用括号括住现有查询,然后用.ToList和.Select连续链接。但是是的,你的建议最终解决了问题。谢谢你的建议和解释。
from tempResult in (from t1 in Table1
                    join t2 in Table2
                    on t1.Table2ID equals t2.ID
                    select new TempResult
                    {
                        Number = t1.Number,
                        Code = t2.Code,
                        Sequence = t2.Sequence
                    }).AsEnumerable()
                      .GroupBy(x => x.Number)
                      .Select(x => new Result { Number = x.Key, Codes = string.Join(", ", x.OrderBy(y => y.Sequence).Select(y => y.Code)) })
select tempResult
from otherResult1 in resultFromAnotherQuery1
join result in (from tempResult in (from t1 in Table1
                                    join t2 in Table2
                                    on t1.Table2ID equals t2.ID
                                    select new TempResult
                                    {
                                        Number = t1.Number,
                                        Code = t2.Code,
                                        Sequence = t2.Sequence
                                    }).AsEnumerable()
                                      .GroupBy(x => x.Number)
                                      .Select(x => new Result { Number = x.Key, Codes = string.Join(", ", x.OrderBy(y => y.Sequence).Select(y => y.Code)) })
                select tempResult).ToList()
on otherResult1.Number equals result.Number
join otherResult2 in resultfromAnotherQuery2
on otherResult1.ColumnA equals otherResult2.ColumnB
.....
select new FinalResult
{
    .......
    Codes = result.Codes,
    .......
}