我在几个表之间有一个复杂的连接,但我设法使用linqpad和下面的小表复制错误。 COLNAME列和YAXIS列之间以及未明确定义的COLNAME和XAXIS之间存在引用。
错误是“指定的强制转换无效”,最初我浪费时间认为问题是将数据转换回VS 2010中的对象,但错误也发生在没有定义对象的linqpad中。有点列会引起这个问题似乎很疯狂。如果我将列类型更改为VARCHAR它可以正常工作。如果我从linqpad或sql profiler运行生成的SQL也返回正常。
发生了什么事?
CREATE TABLE TEST_QUERY
([ID] INT IDENTITY(1,1) PRIMARY KEY,
blah VARCHAR(20))
CREATE TABLE TEST_QUERY_COLS
(QUERYID INT NOT NULL,
COLNAME VARCHAR(20) NOT NULL,
otherblah VARCHAR(20),
PRIMARY KEY(QUERYID,COLNAME))
CREATE TABLE TEST_CHART
(CHARTID INT IDENTITY(1,1) PRIMARY KEY,
QUERYID INT NOT NULL REFERENCES TEST_QUERY([ID]),
XAXIS VARCHAR(20) NOT NULL,
blahblah VARCHAR(20))
CREATE TABLE TEST_CHART_SERIES
(CHARTID INT NOT NULL REFERENCES TEST_CHART(CHARTID),
YAXIS VARCHAR(20) NOT NULL,
blahblahblah BIT NOT NULL,
PRIMARY KEY(CHARTID,YAXIS))
INSERT INTO TEST_QUERY(blah) VALUES('xxx')
INSERT INTO TEST_QUERY_COLS(QUERYID,COLNAME,otherblah) VALUES(1,'col1','xxx')
INSERT INTO TEST_QUERY_COLS(QUERYID,COLNAME,otherblah) VALUES(1,'col2','yyy')
INSERT INTO TEST_CHART(QUERYID,XAXIS,blahblah) VALUES(1,'col1','xxx')
INSERT INTO TEST_CHART_SERIES(CHARTID,YAXIS,blahblahblah) VALUES(1,'col2',1)
这是linq声明:
((from ch in TEST_CHARTs
join a in TEST_CHART_SERIES on ch.CHARTID equals a.CHARTID into a_join
from cs in a_join.DefaultIfEmpty()
join ycols in TEST_QUERY_COLS on new { key1 = cs.YAXIS, key2 = ch.QUERYID } equals new { key1 = ycols.COLNAME, key2 = ycols.QUERYID }
where ch.CHARTID == 1
select new
{
ch.CHARTID,
POSITION = 0,
ycols.QUERYID,
ycols.Otherblah,
cs.Blahblahblah
})
.Union(from ch in TEST_CHARTs
join xcol in TEST_QUERY_COLS on new { key1 = ch.XAXIS, key2 = ch.QUERYID } equals new { key1 = xcol.COLNAME, key2 = xcol.QUERYID }
where ch.CHARTID == 1
select new
{
ch.CHARTID,
POSITION = 0,
xcol.QUERYID,
xcol.Otherblah,
Blahblahblah = false
})).Distinct()
修改:我已向微软提交了一个错误here
答案 0 :(得分:3)
生成的sql包含以下行,其中@ p4对应于投影中的Blahblahblah=false
行:
DECLARE @p4 Int = 0
从查询返回的int无法转换为bool。我不知道这是否是一个linq to sql bug(看起来像它),但有一个解决方法。基本上你需要从预测的匿名类型中删除Blahblahblah=false
,然后从结果.ToList()
或.ToArray()
中删除,最后将linq中的bool字段添加到对象投影中:
var one =
(from ch in TEST_CHARTs
join a in TEST_CHART_SERIES on ch.CHARTID equals a.CHARTID into a_join
from cs in a_join.DefaultIfEmpty()
join ycols in TEST_QUERY_COLS on new { key1 = cs.YAXIS, key2 = ch.QUERYID } equals new { key1 = ycols.COLNAME, key2 = ycols.QUERYID }
where ch.CHARTID == 1
select new
{
ch.CHARTID,
POSITION = 0,
ycols.QUERYID,
ycols.Otherblah,
Blahblahblah = cs.Blahblahblah
}).ToList();
var two =
(from ch in TEST_CHARTs
join xcol in TEST_QUERY_COLS on new { key1 = ch.XAXIS, key2 = ch.QUERYID } equals new { key1 = xcol.COLNAME, key2 = xcol.QUERYID }
where ch.CHARTID == 1
select new
{
ch.CHARTID,
POSITION = 0,
xcol.QUERYID,
xcol.Otherblah
}).ToList();
var three =
from x in two
select new
{
x.CHARTID,
x.POSITION,
x.QUERYID,
x.Otherblah,
Blahblahblah = false
};
var four = one.Union(three).Distinct();
请注意,这导致两个sql查询,而不是一个。
修改强>
此外,可以省略Distinct(),因为union不包含重复项。我应该读取我复制和粘贴的代码!