当前位置: 首页 > 编程语言 > C#

Linq2Sql – 使用本地集合作为子查询的一部分 – “不支持使用本地集合的查询”分享

时间:2023-04-10 20:27:59 C#

C#学习教程:Linq2Sql-使用本地集合作为子查询的一部分-“不支持使用本地集合进行查询”上次我发布这个(上周)时,我没有正确描述问题。我已经为这个问题创建了一个简单的例子。查询本地集合可以很好地使用它作为基本查询的一部分。我发现的问题是将它与子查询的一部分一起使用。例如。不提供数据库图或代码图很难描述,但我会尽力而为。我正在尝试通过一个查询将我的代码执行到数据库。我不想破坏它并发送多个命令。这样做有一些好处,包括避免可能出现的问题,我将在本文最后解释。我正在加入一些有关系的表。属性(DataEventAttributes)表当然描述了主表(DataEvents)中特定行的唯一属性。当我在没有任何本地集合的情况下查询它时,它对我的??20gig数据库运行良好且速度极快。但是,如果我将本地值集合作为获取结果的子查询的一部分,我会得到“不支持使用本地集合的查询”,这对我来说很难在我的代码中重现,所以我会评论它,我可以用我正在做的事做你能做的事。//获取初始查询并加入。我们实际上最后只关心ID,但是我们使用连接的数据//来确定是否需要拉取一行。varinitialQuery=fromdataEventinDataEvent.GetByQueryExpression(context)joinattributeinDataEventAttribute.GetByQueryExpression(context)ondataEvent.DataEventIDequalsattribute.DataEventIDselectnew{ID=dataEvent.DataEventID,PluginID=dataEvent.DataOwnerID,TimeStamp=dataEvent.DataTimeStamp,DataEventKeyID=attribute.DataEventKeyID,ValueString=attribute.ValueString,ValueDecimal=attribute.ValueDecimal};//我们需要在最终查询之前确认初始查询中存在的一些id列表varsomeSetOfIDs=newList(){1,2,3,4,5};//这是在我在最终查询中重建整个结果集之前过滤掉一些结果的本地集合//如果你注释掉这一行,finalQuery将执行得很好。//有了这个,“查询withlocalcollectionsarenotsupported”错误会出现。initialQuery=initialQuery.Where(x=>x.DataEventKeyID==1&&someSetOfIDs.Contains((int)x.ValueDecimal));//子查询的可重用查询结果——不是问题的一部分,只是例子的一部分删除集合中可能存在的任何重复项。//选择键正在获取我需要的ID//选择ID是分组的第一个项目的ID。//contains将本地dataEvent对象与ID进行比较表(检查它是否存在)//结果只是我可以使用新类型varfinalQuery=fromdataEventinDataEvent.GetByQueryExpression(context)whereinitialQuery.GroupBy(x=&g吨;x).Select(x=>x.Key).Select(x=>x.ID).Contains(dataEvent.DataEventID)选择新的{BasicData=attributeBaseQuery.Where(attrValue=>attrValue.DataEventID==dataEvent.DataEventID&&attrValue.DataEventKeyID==(短)DataEventTypesEnum.BasicData).FirstOrDefault().ValueString};varfinalResult=finalQuery.Take(100).ToList();我发现的一个解决方案是在finalQuery.Select(x=>x.ID)执行.ToList()之后,但副作用有两个负面影响,它首先运行该查询,然后从数据库中获取ID..然后它必须将这些结果作为参数传递给sqlserver作为finalQuery参数。第二个主要(显示停止)是如果.ToList()有很多结果,SQL服务器会抛出一些奇怪的错误消息,谷歌搜索显示有很多参数被传递(这是有道理的,因为参数计数可以是10-100(千)。也就是说,我试图弄清楚如何构建一个查询,我可以在其中动态调整条件,然后使用与符合子查询条件的ID匹配的所有属性重建我的结果集。在SQLThisworksgreatontheserverviastudio,但集合问题让我卡住了。我尝试了很多不同的东西,但它似乎重现这个的唯一方法是使用本地集合的查询,然后将该查询用作另一个查询的一部分,其中第一个查询过滤结果。有什么想法可以做到这一点吗?屏幕截图显示您知道我并不疯狂。在此先感谢您提供的任何帮助AFAIK,这在LINQtoSQL查询中是不可能的使用内存中的集合。我可以想到两种可能的解决方法:选项1:对每个ID执行查询:varsomeSetOfIDs=newList(){1,2,3,4,5};//queryPerID的类型为IEnumerable>varqueryPerID=fromidinsomeSetOfIDsselect(fromdataEventinDataEvent.GetByQueryExpression(context)&&(int)attribute.ValueDecimal==id//从Containsselectnew{ID=dataEvent.DataEventID,PluginID=dataEvent.DataOwnerID,TimeStamp=dataEvent.DataTimeStamp,DataEventKeyID=attribute.DataEventKeyID,ValueString=attribute.ValueString,ValueDecimal=attribute.ValueDecimal});//对于这些查询中的每一个,我们都有一个等效的最终可查询varres=frominitialQueryinqueryPerIDselect(fromdataEventinDataEvent.GetByQueryExpression(context)whereinitialQuery.GroupBy(x=>x).Select(x=>x.Key.ID).Contains(dataEvent.DataEventID)选择new{BasicData=attributeBaseQuery.Where(attrValue=>attrValue.DataEventID==dataEvent.DataEventID&&attrValue.DataEventKeyID==(short)DataEventTypesEnum.BasicData).FirstOrDefault().ValueString})intofinalQueryfromxinfinalQueryvarselectx;finalResult=finalQuery.Take(100).ToList();我不确定它是否会编译,但它应该非常接近选项2:从someSetOfIDs构建一个谓词表达式以传递给SQL。varsomeSetOfIDs=newList(){1,2,3,4,5};表达式>seed=x=>false;varpredicate=someSetOfIDs。聚合(种子,(e,i)=>Expression.Lambda>(Expression.OrElse(Expression.Equal(Expression.Property(e.Parameters[0],“ValueDecimal”),Expression.Constant(i)),e。体),e.Parameters));基本上我们已经构建了一个where子句:x=>((x.ValueDecimal=5)||((x.ValueDecimal=4)||((x.ValueDecimal=3)||((x.ValueDecimal=2)||((x.ValueDecimal=1)||False)))))请务必注意,此方法不适用于匿名类型,因此您必须对具有命名类型的可查询对象使用谓词。如果您重新组织一下(这实际上可能会产生更好的查询计划),这不是问题:varattributes=DataEventAttribute.GetByQueryExpression(context).Where(a=>a.DataEventKeyID==1).Where(predicate);varinitialQuery=fromdataEventinDataEvent.GetByQueryExpression(context)joinattributeinattributesselectnew{ID=dataEvent.DataEventID,PluginID=dataEvent.DataOwnerID,TimeStamp=dataEvent.DataTimeStamp,DataEventKeyID=attribute.DataEventValueDetributeKeyValid,ValueString==attribute.ValueDecimal};我不是这方面的专家,但LinqToSql的工作原理是构建一个在执行时转换为SQL查询的表达式树。如果您的所有查询都可以转换为SQL,则此方法可以正常工作。但是,您所做的基本上是尝试使用.NET对象集合来加入SQL查询。问题是,这不起作用,因为连接不能转换为SQL查询。您正在混合两种不同的东西-LinqToSql和LinqToObjects。在LinqToSql上调用ToList()使其工作,因为您回到了LinqToObjects的域中。对不起,恐怕我不知道这件事。附言。可能看到这个问题:Linq2Sql->Searchingdatabaseagainstlocalvaluesets-Queriesusinglocalcollectionsnotsupported如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: