EF 5在简单选择时不必要地执行LEFT OUTER JOIN

时间:2013-09-23 10:56:00

标签: .net sql-server entity-framework entity-framework-5

执行如下步骤:

using (var DB = new SiteEntities())
{
  var test = DB.All<AssessmentItem>();
}

这个SQL查询的结果,为什么要执行连接?!我没有声明查询Products表,它导致我重复数据的问题。我从未见过这种行为。

SELECT 
[Extent1].[ID] AS [ID], 
[Extent1].[Name] AS [Name], 
[Extent1].[Description] AS [Description], 
[Extent1].[Status] AS [Status], 
[Extent1].[UpdatedAt] AS [UpdatedAt], 
[Extent1].[CreatedAt] AS [CreatedAt], 
[Extent1].[Alias] AS [Alias], 
[Extent1].[ImageFileName] AS [ImageFileName], 
[Extent1].[ReplacementCost] AS [ReplacementCost], 
[Extent2].[ID] AS [ID1]
FROM  [dbo].[AssessmentItems] AS [Extent1]
LEFT OUTER JOIN [dbo].[Products] AS [Extent2] ON ([Extent2].[AssessmentItemID] IS NOT NULL) AND ([Extent1].[ID] = [Extent2].[AssessmentItemID])

这是我的Entity Framework生成的AssessmentItem.cs:

public partial class AssessmentItem
{
    public AssessmentItem()
    {
        this.AssessmentItemAttributeMappings = new HashSet<AssessmentItemAttributeMapping>();
        this.CustomerAssessmentItems = new HashSet<CustomerAssessmentItem>();
    }

    public int ID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public byte Status { get; set; }
    public Nullable<System.DateTime> UpdatedAt { get; set; }
    public System.DateTime CreatedAt { get; set; }
    public string Alias { get; set; }
    public string ImageFileName { get; set; }
    public Nullable<decimal> ReplacementCost { get; set; }

    public virtual ICollection<AssessmentItemAttributeMapping> AssessmentItemAttributeMappings { get; set; }
    public virtual ICollection<CustomerAssessmentItem> CustomerAssessmentItems { get; set; }
    public virtual Product Product { get; set; }
}

更新

using (var DB = new SiteEntities())
{
  var test = DB.All<AssessmentItem>()
      .Select(x => new
        {
            x.ID,
            x.Name
        });
}

产生正确的SQL查询,必须在后台进行某种时髦的推断。我仍然想知道是否有人对此有任何想法。

2 个答案:

答案 0 :(得分:1)

好的,我发现了这个问题,看来我在EF中建立了AssessmentItem<>Product关系作为1-1的关系。作为副产品,在Products表上没有任何AssessmentItemID INT外键,因为删除它是由我遵循的说明建议的,如果没有删除它将无法工作,这似乎是问题,就像我去的那样为了保存我迄今尚未完成的Product记录,它抱怨失踪的FK。图两个问题都是相关的,将Products表重新添加到EF设计器表面修复它。

谢谢你们对我耐心。我真的认为EF应该能够更容易地执行1-1关系,我现在只需要每次我想访问它时只需要.Single()。 :(

答案 1 :(得分:0)

DbSet.All通常用于测试序列中的项是否满足特定谓词..在您的情况下,您没有提供任何谓词,而且它似乎正在做一个急切的负载。

在您的情况下,它需要Func<AssessmentItem, bool>作为谓词

如果你只是想要所有的项目,为什么不简单地说。

DB.AssessmentItems;