EF6 - 导航属性 - 单个项目而不是集合

时间:2017-06-09 13:13:36

标签: c# entity-framework

我有以下课程设置:

public class GuestDefinition
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<GuestItem> GuestItems { get; set; }
}

public class GuestItem
{
    public int Id { get; set; }

    [Index(IsUnique =true)]
    public int InvitationId { get; set; }
    public virtual Invitation Invitation { get; set; }

    public int GuestDefinitionId { get; set; }
    public virtual GuestDefinition GuestDefinition { get; set; }
}

public class Invitation
{
    public int Id { get; set; }
    public virtual GuestItem GuestItem { get; set; }
}

当尝试应用以下实体框架时,会生成不正确的查询

var entry = db.Invitations.Select(p => new
{
    Id = p.Id,
    Name = p.GuestItem.GuestDefinition.Name
}).FirstOrDefault();

来自EF的生成查询是:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent3].[Name] AS [Name]
FROM   [dbo].[Invitation] AS [Extent1]
LEFT OUTER JOIN [dbo].[GuestItems] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[GuestDefinition] AS [Extent3] ON [Extent2].[GuestDefinitionId] = [Extent3].[Id]
WHERE [Extent1].[Id] = @p__linq__0

问题在于第一个连接线,正确的连接应该是

LEFT OUTER JOIN [dbo].[GuestItems] AS [Extent2] ON [Extent1].[Id] = [Extent2].[InvitationId]

除了将邀请的GuestItem转换为ICollection之外,还有什么方法可以完成这项工作吗?由于我的用例,我想防止在每次加入呼叫时使用FirstOrDefault()

1 个答案:

答案 0 :(得分:2)

你的关系是1:1。在EF中,该技术是将非主体ID定义为KEY和FK。例如:

public class GuestItem
{
    public int Id { get; set; }

    public int GuestDefinitionId { get; set; }
    public virtual GuestDefinition GuestDefinition { get; set; }

    public virtual Invitation Invitation { get; set; }
}

public class Invitation
{
    [Key, ForeignKey("GuestItem")]
    public int GuestItemId { get; set; }
    public virtual GuestItem GuestItem { get; set; }
}

或者如果您更喜欢流利的代码:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Configure GuestItemId as PK for GuestItem
    modelBuilder.Entity<GuestItem>()
        .HasKey(e => e.GuestItemId);

    // Configure GuestItemId as FK for GuestItem
    modelBuilder.Entity<GuestItem>()
                .HasOptional(s => s.Invitation) 
                .WithRequired(ad => ad.GuestItemId); 

}

请参阅here