C# 在查询结果上加入列表时出现Linq异常
我有一份清单:C# 在查询结果上加入列表时出现Linq异常,c#,sql,linq,exception,join,C#,Sql,Linq,Exception,Join,我有一份清单: List<MyClass> lstClass1; 我在DB上有一个表MyTable要查询,其中有两个字符串类型的列: MyTable column MainKey column AlternativeKey 对于我的脚本,我必须按照以下规则选择DB和列表的连接:如果AlternativeKey存在,如果AlternativeKey中的前4个字符等于MyClass.property1或MyClass.Property2,则选择行;否则,如果MainKey
List<MyClass> lstClass1;
我在DB上有一个表MyTable要查询,其中有两个字符串类型的列:
MyTable
column MainKey
column AlternativeKey
对于我的脚本,我必须按照以下规则选择DB和列表的连接:如果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);
IQueryable source=getMyTable();
List lstclas1=getListClass();
IQueryable qMyClassList=lstClass1.AsQueryable();
IQueryable selAlternative=源中的alt
在上的qMyClassList中加入cl1
alt.AlternativeKey.子字符串(0,4)
等于cl1.property1
在上的qMyClassList中加入cl2
alt.AlternativeKey.子字符串(0,4)
等于cl2.property2
何处alt.AlternativeKey!=null&&alt.AlternativeKey.Length>=4
选择alt;
IQueryable selMain=源中的主节点
在上的qMyClassList中加入cl1
main.MainKey.Substring(0,4)
等于cl1.property1
在上的qMyClassList中加入cl2
main.MainKey.Substring(0,4)
等于cl2.property2
其中main.AlternativeKey==null&&main.MainKey.Length>=4
选择main;
source=alt.Union(main);
在执行过程中,当我在结果元素上循环时,此查询引发此异常:
无法创建“MyTable+MyClass”类型的常量值。只有
在此上下文中支持基元类型或枚举类型
我做错了什么?您正在将内存集合:
qMyClassList
加入到IQueryable
数据源。例外情况是因为IQueryable LINQ提供程序无法将连接转换为相关查询
2个选项,您可以考虑:
选项1:您可以尝试使用中的包含,而不是加入。您的LINQ查询提供程序可以将您的查询解释为WHERE。。在('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;
IQueryable<MyTable> source = getMyTable();
List<MyClass> lstClass1 = getListClass();
var property1List = (from prp in lstClass1 select prp.property1).Distinct();
var property2List = (from prp in lstClass1 select prp.property2).Distinct();
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;
var selMain = from main in source
where main.AlternativeKey == null &&
(property1List.Contains(main.MainKey.Substring(0, 4)) ||
property2List.Contains(main.MainKey.Substring(0, 4)))
select main;
source = alt.Union(main);
请记住,Contains
仅适用于基本类型。在您的情况下,这似乎是一个字符串
,因此没有问题
选项2,如果您想保持加入状态,只需.ToList()
您的源实例即可。如果您的源很大,这通常不是一个好主意,因为您将整个数据集加载到内存中,并在内存中应用联接。):
Niels,选项1是一个很好的建议,但我必须这样过滤:
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;
IQueryable<MyTable> source = getMyTable();
List<MyClass> lstClass1 = getListClass();
var property1List = (from prp in lstClass1 select prp.property1).Distinct();
var property2List = (from prp in lstClass1 select prp.property2).Distinct();
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;
var selMain = from main in source
where main.AlternativeKey == null &&
(property1List.Contains(main.MainKey.Substring(0, 4)) ||
property2List.Contains(main.MainKey.Substring(0, 4)))
select main;
source = alt.Union(main);
IQueryable source=getMyTable();
List lstclas1=getListClass();
var property1List=(从lstClass1中的prp选择prp.property1.Distinct();
var property2List=(从lstClass1中的prp中选择prp.property2.Distinct();
var SELALTERNATION=源中的alt
何处alt.AlternativeKey!=空的&&
(property1List.Contains(alt.AlternativeKey.Substring(0,4))||
property2List.Contains(alt.AlternativeKey.Substring(0,4)))
选择alt;
var selMain=源中的主节点
其中main.AlternativeKey==null&&
(property1List.Contains(main.MainKey.Substring(0,4))||
property2List.Contains(main.MainKey.Substring(0,4)))
选择main;
source=alt.Union(main);
谢谢大家! 请尝试在查询中不要使用相等运算符(“==”)。如果MyClass
的列表已在内存中,我怀疑删除。AsQueryable()
会立即清除该列表。(编辑:好的,不要声明它是可查询的)注意两个包含的是!