【问题标题】:Different results from [ForeignKey] attribute vs. OnModelCreating or EntityTypeConfiguration[ForeignKey] 属性与 OnModelCreating 或 EntityTypeConfiguration 的不同结果
【发布时间】:2013-10-31 19:51:47
【问题描述】:

对于背景:我试图让我的 EF POCO 不受对 EF 的引用,因此所有模型配置代码都将进入 OnModelCreating 或 EntityTypeConfiguration 类,而不是使用属性(从而避免对 System.ComponentModel.DataAnnotations 的引用。架构)。问题是当外键不是由属性建立时,它似乎在构建模型时被忽略了。这是一个例子:

public class Person
{
    public int Id { get; set; }
    [ForeignKey("Group")]
    public int? GroupId { get; set; }
    public Group Group { get; set; }
}
public class Group
{
    public int Id { get; set; }
    public List<Person> People { get; set; }
}
public class Context : DbContext
{
    public DbSet<Group> Groups { get; set; }
    public DbSet<Person> People { get; set; }
}

生成这个:

create table [dbo].[Groups] (
    [Id] [int] not null identity,
    primary key ([Id])
);
create table [dbo].[People] (
    [Id] [int] not null identity,
    [GroupId] [int] null,
    primary key ([Id])
);
alter table [dbo].[People] add constraint [Person_Group] foreign key ([GroupId]) references [dbo].[Groups]([Id]);

完美。

但将其移至 OnModelCreating(或等效的 EntityTypeConfiguration 代码),如下所示:

modelBuilder.Entity<Person>()
    .HasOptional(t => t.Group)
    .WithMany()
    .HasForeignKey(t => t.GroupId);

结果是这样的(对于新的或迁移的数据库):

create table [dbo].[Groups] (***same as above***);
create table [dbo].[People] (
    [Id] [int] not null identity,
    [GroupId] [int] null,
    [Group_Id] [int] null,
    primary key ([Id])
);
alter table [dbo].[People] add constraint [Group_People] foreign key ([Group_Id]) references [dbo].[Groups]([Id]);
alter table [dbo].[People] add constraint [Person_Group] foreign key ([GroupId]) references [dbo].[Groups]([Id]);

为什么要创建 Group_Id 而为什么不使用 GroupId?

谢谢!

【问题讨论】:

  • 我应该指出,我知道在这种情况下不使用属性或流式 API 会起作用,因为 EF 足够聪明,可以将 GroupId 作为 FK。但这不是重点。首先,因为如果它是 GroupFK 而不是 GroupId (至少没有调整约定),那将是不正确的。其次,更重要的是,我想了解为什么它在这种情况下会做出这种区分,尤其是因为它足够聪明,可以在所有其他情况下弄清楚。

标签: entity-framework entity-framework-5 entity-framework-6


【解决方案1】:

您的映射似乎有误。

由于您在 Group 中有一个导航属性,因此您需要将其包含在映射中,如下所示:

modelBuilder.Entity<Person>()
    .HasOptional(t => t.Group)
    .WithMany(t => t.People) // <---
    .HasForeignKey(t => t.GroupId);

否则 EF 会将导航属性用于两个实体之间的不同关系并创建另一个外键。

【讨论】:

  • 看来我标记得太快了。是的,这在 OnModelCreating 中确实有效,但我只是将它放入 EntityTypeConfiguration 类中,但它失败了。与上述相同的问题,添加 Patient_Id。
  • @Ryan - 听起来不太可能 - 您确定 EntityTypeConfiguration 已连接到 OnModelCreating 方法中吗?
猜你喜欢
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-19
  • 2020-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多