admin

在查询结果上加入列表时的Linq异常

sql

我有一个清单:

List<MyClass> lstClass1;

其中MyClass具有2个简单的字符串属性:

class MyClass
{
   public string property1 { get; set; }
   public string property2 { get; set; }
}

我在数据库MyTable上有一个要查询的表,其中有两个字符串类型列:

MyTable
   column MainKey
   column AlternativeKey

对于我的脚本,我必须选择数据库和列表的联接,并遵循以下规则:如果AlternativeKey存在,则AlternativeKey中的前4个字符等于MyClass.property1或MyClass.Property2时,选择行;否则,选择行。
MainKey中的前4个字符等于MyClass.property1或MyClass.Property2。这是我的实现:

IQueryable<MyTable> source = getMyTable();
List<MyClass> lstClass1 = getListClass();

IQueryable<MyClass> qMyClassList = lstClass1.AsQueryable<MyClass>();

IQueryable<MyTable> selAlternative = from alt in source
                                     join cl1 in qMyClassList on
                                     alt.AlternativeKey.Substring(0, 4)
                                     equals cl1.property1
                                     join cl2 in qMyClassList on
                                     alt.AlternativeKey.Substring(0, 4)
                                     equals cl2.property2
                                     where alt.AlternativeKey != null && alt.AlternativeKey.Length >= 4
                                     select alt;

IQueryable<MyTable> selMain = from main in source
                                     join cl1 in qMyClassList on
                                     main.MainKey.Substring(0, 4)
                                     equals cl1.property1
                                     join cl2 in qMyClassList on
                                     main.MainKey.Substring(0, 4)
                                     equals cl2.property2
                                     where main.AlternativeKey == null && main.MainKey.Length >= 4
                                     select main;

source = alt.Union(main);

在执行中,当我在result元素上循环时,此查询引发此异常:

无法创建类型为’MyTable + MyClass’的常量值。在此上下文中仅支持原始类型或枚举类型。

我做错了什么?


阅读 156

收藏
2021-06-07

共1个答案

admin

您正在将一个 内存 集合加入:qMyClassList到一个IQueryable数据源。例外是因为IQueryable
LINQ提供程序无法将转换join为相关查询。

2个选项,您可以考虑:

选择1: 你可以尝试使用Containswhere替代join。您的LINQ查询提供程序可能将您的查询解释为WHERE .. IN ('val1','val2'...)。因此,对于您来说,它看起来像这样:

var selAlternative = from alt in source 
                     where alt.AlternativeKey != null &&
                           property1List.Contains(alt.AlternativeKey.Substring(0, 4)) &&
                           property2List.Contains(alt.AlternativeKey.Substring(0, 4)) &&
                     select alt;

请记住,Contains这仅适用于原始类型。在您的情况下,这似乎是string,所以很好。

选项2
,如果你想保持你的加入为是,只要.ToList()你的source实例。如果您的源很大,这通常不是一个好主意,因为您将整个数据集加载到内存中,并且将联接应用到内存中。):

var selAlternative = from alt in source.ToList()
                     join cl1 in qMyClassList on ...
2021-06-07