我坚持从LINQToSQL转换左外连接,返回唯一的父行。

我有2个表(Project,Project_Notes,它是由Project_ID链接的1-many关系)。我在2表上的多个列上进行关键字搜索,如果Project_Notes中的列包含关键字,我只想返回唯一项目。我有这个linqtoSQl序列,但它似乎返回多个Project行。也许在LINQ中以某种方式做一个Exist?或者也许是某种类型的群体?

这是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;

这是从profiler

生成的SQL
  

exec sp_executesql N'SELECT [t2]。[Title],[t2]。[State],[t2]。[PROJECT_ID],   [t2]。[PROVIDER_ID],[t2]。[CATEGORY_ID],[t2]。[城市],[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]。[城市],[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] <!> gt; = @ p1)AND([t0]。[SubmittedDate] <!> lt; @ p2)AND([t0]。[PROVIDER_ID] =   @ p3)AND([t0]。[CATEGORY_ID]为空))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

此查询返回结果中1-many关系的所有多个部分。我在这里找到了如何在LINQ中执行Exists http:/ /www.linq-to-sql.com/linq-to-sql/t-sql-to-linq-upgrade/linq-exists/

这是使用databind()的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;

生成的SQL语句:

  

exec sp_executesql N'SELECT COUNT(*)AS [value] FROM [dbo]。[PROJECTS] AS [t0] WHERE   (EXISTS(从[dbo]中选择NULL [EMPTY]。[PROJECT_NOTES] AS [t1] WHERE   ([t1] .PROJECT_ID] =([t0]。[PROJECT_ID]))AND([t1]。[NOTES] LIKE @ p0)))AND   ([t0]。[SubmittedDate] <!> gt; = @ p1)AND([t0]。[SubmittedDate] <!> lt; @ 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

我使用<=>从<=>获得SQL超时。

有帮助吗?

解决方案

  

它似乎正在返回多个项目行

是的,这就是加入的方式。如果一个项目有5个匹配的笔记,它会显示5次。


如果问题是什么 - <!>“加入<!>”;是错误的成语!

您希望将项目过滤到其注释包含特定文本的项目:

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

其他提示

您将不得不使用DefaultIfEmpty扩展方法。关于SO的一些问题已经显示出如何做到这一点。这是一个很好的例子:

如何执行在LINQ中嵌套了Join,Add和Group?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top