我有以下课程设置:
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()
答案 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