LINQ例外情况:“;不支持使用本地集合进行查询。”;但不使用本地集合

LINQ例外情况:“;不支持使用本地集合进行查询。”;但不使用本地集合,linq,exception,datacontext,Linq,Exception,Datacontext,以AdventureWorks数据库的Products表为例,我创建了一个DBML,并扩展了DataContext的属性以包含一个新属性: partial class AdventureWorksDataContext { public IQueryable<Product> FinishedProducts { get { return Products.Where(p => p.FinishedGoodsFlag); } } } 部分类数据上下文 { 公共可液

以AdventureWorks数据库的Products表为例,我创建了一个DBML,并扩展了DataContext的属性以包含一个新属性:

partial class AdventureWorksDataContext { public IQueryable<Product> FinishedProducts { get { return Products.Where(p => p.FinishedGoodsFlag); } } } 部分类数据上下文 { 公共可液化成品 { 获取{return Products.Where(p=>p.finishedgoodssflag);} } } Products属性是生成的DataContext的一部分,我所做的只是从表中添加一个Where,以便它返回一个IQueryable

现在,当试图像这样查询它时,问题出现了(愚蠢的示例,但应该会显示问题):

var queryFinishedProducts=datacontext.FinishedProducts.Where(fp=>fp.ProductID==datacontext.FinishedProducts.Max(p=>p.ProductID))

迭代此查询会导致“不支持使用本地集合的查询”异常。我不明白为什么在没有使用本地集合的情况下它会抛出这个错误。如果我在普通产品表(这是一个
)上运行它:

var queryProducts=datacontext.FinishedProducts.Where(fp=>fp.ProductID==datacontext.Products.Max(p=>p.ProductID))

…很好用。唯一的区别是我在
表中添加了一个Where,并将其作为
IQueryable
返回


有人有什么想法吗

以下是一种可行的方法:

var max = datacontext.FinishedProducts.Max(p => p.ProductID);
var queryFinishedProducts = datacontext.FinishedProducts
                                       .Where(fp => fp.ProductID == max);
或者假设
ProductID
是唯一的,尝试按如下方式重写查询:

var queryProducts = datacontext.FinishedProducts
                               .OrderByDescending(p => p.ProductID)
                               .First();

以下是一种可行的方法:

var max = datacontext.FinishedProducts.Max(p => p.ProductID);
var queryFinishedProducts = datacontext.FinishedProducts
                                       .Where(fp => fp.ProductID == max);
或者假设
ProductID
是唯一的,尝试按如下方式重写查询:

var queryProducts = datacontext.FinishedProducts
                               .OrderByDescending(p => p.ProductID)
                               .First();

我能够重现这种行为。以下是反射器中要查看的更多类型:

System.Data.Linq.SqlClient.SqlBinder.Visitor
System.Data.Linq.SqlClient.SqlVisitor
基于此堆栈跟踪

at System.Data.Linq.SqlClient.SqlBinder.Visitor.ConvertToFetchedSequence(SqlNode node)
at ..SqlBinder.Visitor.VisitAlias(SqlAlias a)
at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)
at ..SqlVisitor.VisitSource(SqlSource source)
at ..SqlBinder.Visitor.VisitSelect(SqlSelect select)
at ..SqlVisitor.Visit(SqlNode node)
at ..SqlBinder.Visitor.VisitAlias(SqlAlias a)
at ..SqlVisitor.Visit(SqlNode node)
at ..SqlVisitor.VisitSource(SqlSource source)
at ..SqlBinder.Visitor.VisitSelect(SqlSelect select)
at ..SqlVisitor.Visit(SqlNode node)
at ..SqlVisitor.VisitSequence(SqlSelect sel)
at ..SqlVisitor.VisitScalarSubSelect(SqlSubSelect ss)
at ..SqlVisitor.VisitSubSelect(SqlSubSelect ss)
at ..SqlBinder.Visitor.VisitSubSelect(SqlSubSelect ss)
我想知道为什么
Table
类型的属性与
IQueryable
或甚至
ITable
类型的属性被区别对待。属性的实现并不重要,返回类型很重要


类型为
IQueryable
的属性与类型为
IQueryable


查询3在查询转换期间急切地发出子查询,然后对主查询进行第二次往返。

我能够重现这种行为。以下是反射器中要查看的更多类型:

System.Data.Linq.SqlClient.SqlBinder.Visitor
System.Data.Linq.SqlClient.SqlVisitor
基于此堆栈跟踪

at System.Data.Linq.SqlClient.SqlBinder.Visitor.ConvertToFetchedSequence(SqlNode node)
at ..SqlBinder.Visitor.VisitAlias(SqlAlias a)
at System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)
at ..SqlVisitor.VisitSource(SqlSource source)
at ..SqlBinder.Visitor.VisitSelect(SqlSelect select)
at ..SqlVisitor.Visit(SqlNode node)
at ..SqlBinder.Visitor.VisitAlias(SqlAlias a)
at ..SqlVisitor.Visit(SqlNode node)
at ..SqlVisitor.VisitSource(SqlSource source)
at ..SqlBinder.Visitor.VisitSelect(SqlSelect select)
at ..SqlVisitor.Visit(SqlNode node)
at ..SqlVisitor.VisitSequence(SqlSelect sel)
at ..SqlVisitor.VisitScalarSubSelect(SqlSubSelect ss)
at ..SqlVisitor.VisitSubSelect(SqlSubSelect ss)
at ..SqlBinder.Visitor.VisitSubSelect(SqlSubSelect ss)
我想知道为什么
Table
类型的属性与
IQueryable
或甚至
ITable
类型的属性被区别对待。属性的实现并不重要,返回类型很重要


类型为
IQueryable
的属性与类型为
IQueryable


query3在查询转换过程中急切地发出子查询,然后对主查询进行第二次往返。

感谢您的回复,不过我更想知道为什么LINQ会以不同的方式处理本质上相同的查询。这个查询实际上只是一个更大问题的例子,那就是lambda能够使用本质上是子选择的东西。@Mike:我认为区别在于
产品
而不仅仅是
IQueryable
,这是一个
。我深入研究了表和DataQuery类的内部,Reflector和Table只实现了CreateQuery方法,并在使用扩展方法时返回DataQuery。话虽如此,这个:Products.Where(p=>p)应该等于返回相同语句的属性,这就是示例所示。这就是我不明白的是,使用Products属性将IQueryable传递回是如何不同的。感谢您的回复,但是我更想知道为什么LINQ会以不同的方式处理本质上相同的查询。这个查询实际上只是一个更大问题的例子,那就是lambda能够使用本质上是子选择的东西。@Mike:我认为区别在于
产品
而不仅仅是
IQueryable
,这是一个
。我深入研究了表和DataQuery类的内部,Reflector和Table只实现了CreateQuery方法,并在使用扩展方法时返回DataQuery。话虽如此,这个:Products.Where(p=>p)应该等于返回相同语句的属性,这就是示例所示。这就是我不明白的,使用Products属性将IQueryable传递回是如何不同的。FinishedProducts是属性吗?“get”在哪里?是的,它是一处地产。抱歉,为了清楚起见,我将添加get。看来SQL生成器无法判断FinishedProducts`查询中使用的
产品
与查询的其余部分来自相同的
DataContext
。FinishedProducts是属性吗?“get”在哪里?是的,它是一处地产。抱歉,为了清楚起见,我将添加get。看来SQL生成器无法判断FinishedProducts`查询中使用的
产品
与查询的其余部分来自相同的
DataContext
。感谢您深入了解LINQ框架!我只是希望我能理解为什么会有不同的对待。我将开始挖掘这些课程,看看还能找到什么。我真的希望这不是第一次出现这种情况,但似乎任何大型项目都可以对表属性进行预筛选。感谢您深入到LINQ框架中!我只是希望我能理解为什么会有不同的对待。我将开始挖掘这些课程,看看还能找到什么。但是,我真的希望这不是第一次出现这种情况,似乎任何大型项目都可以对表属性进行预筛选。