简体   繁体   English

左外部联接并存在于Linq To SQL C#.NET 3.5中

[英]Left Outer Join and Exists in Linq To SQL C# .NET 3.5

I'm stuck on translating a left outer join from LINQToSQL that returns unique parent rows. 我被困在翻译LINQToSQL的左外部联接,该联接返回唯一的父行。

I have 2 tables (Project, Project_Notes, and it's a 1-many relationship linked by Project_ID). 我有2个表(Project,Project_Notes,这是一个由Project_ID链接的1对多关系)。 I am doing a keyword search on multiple columns on the 2 table and I only want to return the unique projects if a column in Project_Notes contains a keyword. 我正在2表的多个列上进行关键字搜索,并且仅当Project_Notes中的列包含关键字时才想返回唯一的项目。 I have this linqtoSQl sequence going but it seems to be returning multiple Project rows. 我有这个linqtoSQl序列,但似乎正在返回多个Project行。 Maybe do an Exist somehow in LINQ? 也许在LINQ中以某种方式Exist Or maybe a groupby of some sort? 或者也许是某种groupby?

Here's the LINQToSQL: 这是LINQToSQL:

 query = from p in query
 join n in notes on p.PROJECT_ID equals n.PROJECT_ID into projectnotes
 from n in notes.DefaultIfEmpty()
 where n.NOTES.Contains(cwForm.search1Form)
 select p;

here's the SQL it produced from profiler 这是它从探查器生成的SQL

exec sp_executesql N'SELECT [t2].[Title], [t2].[State], [t2].[PROJECT_ID], [t2].[PROVIDER_ID], [t2].[CATEGORY_ID], [t2].[City], [t2].[UploadedDate], [t2].[SubmittedDate], [t2].[Project_Type]FROM ( SELECT ROW_NUMBER() OVER (ORDER BY [t0].[UploadedDate]) AS [ROW_NUMBER], [t0].[Title], [t0].[State], [t0].[PROJECT_ID], [t0].[PROVIDER_ID], [t0].[CATEGORY_ID], [t0].[City], [t0].[UploadedDate], [t0].[SubmittedDate], [t0].[Project_Type] FROM [dbo].[PROJECTS] AS [t0] LEFT OUTER JOIN [dbo].[PROJECT_NOTES] AS [t1] ON 1=1 WHERE ([t1].[NOTES] LIKE @p0) AND ([t0].SubmittedDate] >= @p1) AND ([t0].[SubmittedDate] < @p2) AND ([t0].[PROVIDER_ID] = @p3) AND ([t0].[CATEGORY_ID] IS NULL)) AS [t2] WHERE [t2].[ROW_NUMBER] BETWEEN @p4 + 1 AND @p4 + @p5 ORDER BY [t2].[ROW_NUMBER]',N'@p0 varchar(9),@p1 datetime,@p2 datetime,@p3 int,@p4 int,@p5 int',@p0='%chicago%',@p1=''2000-09-02 00:00:00:000'',@p2=''2009-03-02 00:00:00:000'',@p3=1000,@p4=373620,@p5=20 exec sp_executesql N'SELECT [t2]。[Title],[t2]。[State],[t2]。[PROJECT_ID],[t2]。[PROVIDER_ID],[t2]。[CATEGORY_ID],[t2]。[城市],[t2]。[上传日期],[t2]。[提交日期],[t2]。[项目类型] FROM(SELECT ROW_NUMBER()OVER(ORDER BY [t0]。[UploadedDate])AS [ROW_NUMBER],[ t0]。[Title],[t0]。[State],[t0]。[PROJECT_ID],[t0]。[PROVIDER_ID],[t0]。[CATEGORY_ID],[t0]。[城市],[t0] 。[[UploadedDate],[t0]。[SubmittedDate],[t0]。[Project_Type]来自[dbo]。[PROJECTS] AS [t0]左外部联接[dbo]。[PROJECT_NOTES] AS [t1] ON 1 = 1在([t1]。[NOTES]喜欢@ p0)和([t0..SubmittedDate]> = @ p1)和([t0]。[SubmittedDate] <@ p2)和([t0]。[PROVIDER_ID] = @ p3)AND([[t0]。[CATEGORY_ID]为NULL))AS [t2]在[t2]处。[ROW_NUMBER] @ p4 +1和@ p4 + @ p5在[t2]处排序。[ROW_NUMBER]',N '@ p0 varchar(9),@ p1 datetime,@ p2 datetime,@ p3 int,@ p4 int,@ p5 int',@ p0 ='%chicago%',@ p1 =“ 2000-09-02 00: 00:00:000'',@ p2 =''2009-03-02 00:00:00:000'',@ p3 = 1000,@ p4 = 373620,@ p5 = 20

This query returns all mutiples of the 1-many relationship in the results. 此查询在结果中返回“ 1对多”关系的所有信息。 I found how to do an Exists in LINQ from here. 我从这里找到了如何在LINQ中进行Exists http://www.linq-to-sql.com/linq-to-sql/t-sql-to-linq-upgrade/linq-exists/ http://www.linq-to-sql.com/linq-to-sql/t-sql-to-linq-upgrade/linq-exists/

Here is the LINQToSQL using Exists : 这是使用Exists的LINQToSQL:

query = from p in query
where (from n in notes
where n.NOTES.Contains(cwForm.search1Form)
select n.PROJECT_ID).Contains(p.PROJECT_ID)
select p;

The generated SQL statement: 生成的SQL语句:

exec sp_executesql N'SELECT COUNT(*) AS [value] FROM [dbo].[PROJECTS] AS [t0] WHERE (EXISTS(SELECT NULL AS [EMPTY] FROM [dbo].[PROJECT_NOTES] AS [t1] WHERE ([t1].PROJECT_ID] = ([t0].[PROJECT_ID])) AND ([t1].[NOTES] LIKE @p0))) AND ([t0].[SubmittedDate] >= @p1) AND ([t0].[SubmittedDate] < @p2) AND ([t0].[PROVIDER_ID] = @p3) AND ([t0].[CATEGORY_ID] IS NULL)',N'@p0 varchar(9),@p1 datetime,@p2 datetime,@p3 int',@p0='%chicago%',@p1=''2000-09-02 00:00:00:000'',@p2=''2009-03-02 00:00:00:000'',@p3=1000 exec sp_executesql N'SELECT COUNT(*)AS [value] from [dbo]。[PROJECTS] AS [t0] WHERE(EXISTS(SELECT NULL AS [EMPTY] from [dbo]。[PROJECT_NOTES] AS [t1] WHERE([ t1] .PROJECT_ID] =([t0]。[PROJECT_ID])和([t1 .. [NOTES]喜欢@ p0)))和([t0 .. [SubmittedDate]> = @ p1)AND([t0] 。[SubmittedDate] <@ p2)AND([t0]。[PROVIDER_ID] = @ p3)AND([t0]。[CATEGORY_ID] IS NULL)',N'@ p0 varchar(9),@ p1 datetime,@ p2 datetime,@ p3 int',@ p0 ='%chicago%',@ p1 =''2000-09-02 00:00:00:000'',@ p2 =''2009-03-02 00:00: 00:000'',@ p3 = 1000

I get a SQL timeout from the databind() from using Exists . 我通过使用Existsdatabind()得到一个SQL超时。

it seems to be returning multiple Project rows 它似乎正在返回多个项目行

Yes, that's how join works. 是的,这就是联接的工作方式。 If a project has 5 matching notes, it show up 5 times. 如果一个项目有5个匹配的注释,它将显示5次。


What if the problem is - "Join" is the wrong idiom! 如果问题出在哪里-“加入”是错误的习惯用法!

You want to filter the projects to those whose notes contain certain text: 您想要将项目筛选为注释包含某些文本的项目:

var query = db.Project
  .Where(p => p.Notes.Any(n => n.NoteField.Contains(searchString)));

You are going to have to use the DefaultIfEmpty extension method. 您将必须使用DefaultIfEmpty扩展方法。 There are a few questions on SO already that show how to do this. 关于SO的一些问题已经表明了如何执行此操作。 Here is a good example: 这是一个很好的例子:

How can I perform a nested Join, Add, and Group in LINQ? 如何在LINQ中执行嵌套的Join,Add和Group?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM