除Contains()运算符外,本地序列不能用于查询运算符的LINQ to SQL实现

Meh*_*dad 26 c# sql linq

我在我的项目中使用LINQ,我的代码是:

var SE = from c in Shop.Sections
                    join c1 in obj.SectionObjects on c.SectionId equals c1.SectionId
                    select c;

 dataGridView1.DataSource = SE;
Run Code Online (Sandbox Code Playgroud)

但我在行dataGridView1.DataSource = SE;
错误消息中遇到此错误是:

除Contains()运算符外,本地序列不能用于查询运算符的LINQ to SQL实现.

tva*_*son 41

您不能在SQL源和本地源之间使用Join.您需要先将SQL数据放入内存,然后才能加入它们.在这种情况下,你实际上并没有进行连接,因为你只从第一个集合中获取元素,你想要的是一个select ... where ... selectid in query,你可以使用Contains方法获得.

 var SE = Shop.Sections.Where( s => obj.SectionObjects
                                       .Select( so => so.SectionId )
                                       .Contains( s.SectionId ))
                       .ToList();
Run Code Online (Sandbox Code Playgroud)

转换为

select * from Sections where sectionId in (...)
Run Code Online (Sandbox Code Playgroud)

其中in子句的值来自本地对象集合中的id列表.

  • 这不是真的.如果本地源首先使用,则可以使用join.见下面的答案. (3认同)

Che*_*Kot 25

您不能将本地源加入SQL源,但您可以将SQL源加入本地,vv

var SE = from c1 in obj.SectionObjects
              join c in Shop.Sections on c1.SectionId equals c.SectionId
              select c;
Run Code Online (Sandbox Code Playgroud)

换句话说,必须首先考虑本地来源

  • 那应该是公认的答案.在这种方法中,(除非我非常误),SQL源将不会被枚举(因此避免了一些DB开销) (4认同)
  • 如果 db 表很小,则此解决方案有效。但是,它会枚举从数据库到内存的整个表(使用 SQL 跟踪验证)来进行比较。我们有一个复杂的多表“SQL 源到本地”场景,结果开始出现内存不足异常错误。使用 contains 的其他答案允许查询使用“IN”在 SQL Server 上运行,并且只提取相关记录。这些答案应该是公认的答案,尤其是对于较大的表格。 (2认同)

mjw*_*lls 12

这应该可以在数据库端(使用IN)而不是在内存中完成:

var SE = from c in Shop.Sections 
        where obj.SectionObjects.Select(z => z.SectionId).Contains(c.SectionId)
        select c; 
Run Code Online (Sandbox Code Playgroud)

L2S Profiler对这些事情非常有帮助 - 您可以比较我的解决方案和其他解决方案生成的不同SQL.

  • 在数据库端比在内存中快得多! (2认同)