Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在查询结果上加入列表时出现Linq异常_C#_Sql_Linq_Exception_Join - Fatal编程技术网

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()
会立即清除该列表。(编辑:好的,不要声明它是可查询的)注意两个
包含的
是!