我正在与Linq2SQL碰壁。我喜欢它,它的灵活性令人惊叹,但我遇到了有趣的挂断。我希望它只是缺乏对它的了解,而且确实有一个解决方案。举个例子......像这样的linq2sql查询:
//一些本地的ID集合
var terminalID = new List<int>(){1, 2, 3, 4, 5};
// Linq声明的一部分:
queryDataIDs.Where(q => q.DataEventKeyID == 2 && terminalID.Contains((int)q.ValueDecimal));
将导致错误@ runtime
"NotSupportedException was unhandled"
"Queries with local collections are not supported"
堆栈:
at System.Data.Linq.SqlClient.SqlBinder.Visitor.ConvertToFetchedSequence(SqlNode node)
at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitAlias(SqlAlias a)
at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)
at System.Data.Linq.SqlClient.SqlVisitor.VisitSource(SqlSource source)
at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitSelect(SqlSelect select)
at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)
at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitAlias(SqlAlias a)
at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)
at System.Data.Linq.SqlClient.SqlVisitor.VisitSource(SqlSource source)
at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitSelect(SqlSelect select)
at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)
at System.Data.Linq.SqlClient.SqlVisitor.VisitSequence(SqlSelect sel)
at System.Data.Linq.SqlClient.SqlVisitor.VisitExists(SqlSubSelect sqlExpr)
at System.Data.Linq.SqlClient.SqlVisitor.VisitSubSelect(SqlSubSelect ss)
at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitSubSelect(SqlSubSelect ss)
at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)
at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitExpression(SqlExpression expr)
at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitBinaryOperator(SqlBinary bo)
at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)
at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitExpression(SqlExpression expr)
at System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitSelect(SqlSelect select)
at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)
我做错了什么? Google / Bing不会为此报告许多解决方案,但它似乎很直接。
这不是解决方案 - 它不起作用。相同的错误。
Working around LinqToSQls "queries with local collections are not supported" exception
答案 0 :(得分:1)
对不起伙计们,我确实找到了问题所在。问题不是我上面发布的查询,而是来自我在下一个查询中的部分查询中使用它。例如。那个问题让我得到了我需要的ID列表。我在下面使用它是这样的:
where queryDataIDs.Select(x => x.ID).Contains(dataEvent.DataEventID)
但是,它会出错。我试图让它在查询#2的where语句中进行子查询。
如果我这样做:
where queryDataIDs.ToList().Select(x => x.ID).Contains(dataEvent.DataEventID)
没有问题。但问题是它将一个查询转换为两个查询(在sql server级别)。性能很好,因为它在一个连接中处理,但我希望得到一个很好的单个查询来运行。
所以,我为发布错误的代码部分而道歉。似乎Linq2Sql无法像我想做的那样创建一个子查询,但那是一个小小的挫折。
答案 1 :(得分:0)
我无法重现你的问题。我尝试使用对象实例化来查看您的Linq语法是否存在问题,但这有效。所以,我创建了一个Sql表: TestQueryData(DataEventKeyID:int(pk),ValueDecimal:decimal(5,3))
然后我用这个类/表创建了一个LinqToSql dbml,你的代码仍然产生了一个结果。我将布尔值更改为另一个Where语句,并且它在两种情况下仍然有效。
/* // This all works
IQueryable<QueryData> queryDataIDs = new QueryData[]{
new QueryData{DataEventKeyID = 1, ValueDecimal = 2.2m },
new QueryData{DataEventKeyID = 2, ValueDecimal = 2.3m },
new QueryData{DataEventKeyID = 3, ValueDecimal = 2.4m },
new QueryData{DataEventKeyID = 4, ValueDecimal = 2.5m },
new QueryData{DataEventKeyID = 5, ValueDecimal = 2.6m },
new QueryData{DataEventKeyID = 6, ValueDecimal = 2.7m },
new QueryData{DataEventKeyID = 7, ValueDecimal = 2.8m },
new QueryData{DataEventKeyID = 8, ValueDecimal = 2.9m }
}.AsQueryable();
// some local collection of ids
var terminalID = new List<int>(){1, 2, 3, 4, 5};
// a part of a Linq statement:
var selectedValues = queryDataIDs
.Where(q => q.DataEventKeyID == 2)
.Where(q => terminalID.Contains((int)q.ValueDecimal)); */
TestQueryDataDataContext db = new TestQueryDataDataContext();
IQueryable<TestQueryData> queryDataIDs = db.TestQueryDatas;
var terminalID = new List<int>() { 1, 2, 3, 4, 5 };
var selectedValues = queryDataIDs
.Where(q => q.DataEventKeyID == 2)
.Where(q => terminalID.Contains((int)q.ValueDecimal));
我假设您的列表是Ints的通用列表,因为它没有显示在您的帖子中。此外,如果您的数据库表允许ValueDecimal的空值,则必须在尝试强制转换为int之前检查它。
答案 2 :(得分:0)
编辑:看起来你正试图查询queryDataIDs,那是什么?您想查询DataContextInstance.LinqToSqlCollection
var myResults = (
from q in DataContextInstance.LinqToSqlCollection
where q.DataEventKey == 2 && terminalID.Contains((int)q.ValueDecimal)
select q);
或者如果您只想要ID,请将其更改为选择q.DataEventKey而不是选择q
答案 3 :(得分:-1)
您的问题是您正在尝试执行包含“动态”局部变量的SQL查询。 事实是,linq2sql不能像这样进行查询:
select * from table
where id in (--list of ids here referenced from a local variable--)
首先,您应该从数据库中的表中收集列表:
IQueryable<int> terminalID = db.terminals.where(p=>p.id<=5).select(x=>x.id);
然后继续查询:
queryDataIDs.Where(q => q.DataEventKeyID == 2 && terminalID.Contains((int)q.ValueDecimal));
希望有所帮助