2012-01-04 54 views
2

当我尝试连接几个表时,实体框架似乎正在返回整个表。由于这个表格非常大,我需要它只返回所需的行。实体框架正在生成返回整个表的SQL

我有三个表:

Project  - ProjectID, ProjectName 
ProjectEmail - ProjectEmailID, ProjectID, EmailID, RemovedFlag, CreatedBy 
Email   - EmailID, Subject, Body 

我试图检索电子邮件数据的特定项目。 当我这样做:

using (DatabaseEntities context = new DatabaseEntities()) 
{ 
    Project proj = context.Projects.Where(p => p.ProjectID == ProjectID).FirstOrDefault(); 
    if (proj != null) 
    { 
     List<Email> projectEmails = (from pe in proj.ProjectEmails 
            join e in context.Emails on pe.EmailID equals e.EmailID 
            select e).ToList(); 
    } 

} 

所生成的SQL是这样的:

exec sp_executesql N'SELECT TOP (1) 
[Extent1].[ProjectID] AS [ProjectID], 
[Extent1].[ProjectName] AS [ProjectName], 
    -- rest of columns appear here 
FROM [dbo].[Project] AS [Extent1] 
WHERE [Extent1].[ProjectID] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=6 

优秀的,不同之处在于第二个查询产生这样的:

SELECT [Extent1].[EmailID] AS [EmailID], 
    [Extent1].[Subject] AS [Subject], 
      -- rest of columns appear here 
FROM [dbo].[Email] AS [Extent1] 

电子邮件是一个很大的表我真的不想把整个桌子拉回来! 有没有更好的方法来返回邮件列表,以便表 加入正确的密钥?

我也很困惑它是如何知道要返回哪些电子邮件的,因为我看不到第一个 或第二个查询加入ProjectEmail表。

+0

您提供的表定义,EF编写的查询和您说它生成的SQL之间似乎存在断开连接。你说Email表包含EmailID,Subject,Body,并且查询返回整个表,但SQL是通过EmailID和一个未提及的HtmlFlag。介意澄清? – 2012-01-04 04:32:37

+0

对不起,安东尼,我已经缩短了所有的可读性,有更多的专栏,我刚刚删除了不必要的。 – Rocklan 2012-01-04 05:20:32

回答

4

您错过了查询中的where条件。

List<Email> projectEmails = (from pe in proj.ProjectEmails 
          join e in context.Emails on pe.EmailID equals e.EmailID 
          where pe.ProjectID == proj.ProjectID 
          select e).ToList(); 

编辑

您正在使用from pe in proj.ProjectEmails其中proj.ProjectEmails是IEnumerable的类型。所以这个LINQ查询变成了LINQ到对象的查询。这就是为什么它会加载context.Emails中的所有电子邮件。尝试

List<Email> projectEmails = (from pe in context.ProjectEmails 
          join e in context.Emails on pe.EmailID equals e.EmailID 
          where pe.ProjectID == proj.ProjectID 
          select e).ToList(); 
+0

关闭但不完全。 “proj”已经只包含我需要的ProjectEmail,因此将该表连接到Email表上工作正常。查询实际上是返回正确的数据,所以我很难理解它是如何工作的。 – Rocklan 2012-01-04 05:23:44

+0

这很有道理!我已经添加了pe.ProjectID = proj.ProjectID ...并且它现在生成两个查询,哈哈,你必须笑。第一个查询整个Email表,第二个查询ProjectEmail表!我是这个实体框架的新手,我对导航属性一无所知。我是否以正确的方式做这件事? – Rocklan 2012-01-04 05:37:39

+0

@LachlanB检查编辑答案。 – Eranga 2012-01-04 05:38:38