我有一个清单:
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’的常量值。在此上下文中仅支持原始类型或枚举类型。
我做错了什么?
您正在将一个 内存 集合加入:qMyClassList到一个IQueryable数据源。例外是因为IQueryable LINQ提供程序无法将转换join为相关查询。
qMyClassList
IQueryable
join
2个选项,您可以考虑:
选择1: 你可以尝试使用Contains的where替代join。您的LINQ查询提供程序可能将您的查询解释为WHERE .. IN ('val1','val2'...)。因此,对于您来说,它看起来像这样:
Contains
where
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,所以很好。
string
选项2 ,如果你想保持你的加入为是,只要.ToList()你的source实例。如果您的源很大,这通常不是一个好主意,因为您将整个数据集加载到内存中,并且将联接应用到内存中。):
.ToList()
source
var selAlternative = from alt in source.ToList() join cl1 in qMyClassList on ...