【问题标题】:Entity Framework Code First generates two foreign key columns in database when creating a 1:n relationship创建 1:n 关系时,Entity Framework Code First 在数据库中生成两个外键列
【发布时间】:2017-07-21 09:58:27
【问题描述】:

我想使用实体框架创建一个 1:n 关系,基于用于创建关系的命名约定。我正在使用代码优先。 Entity Framework 忽略了约定并且总是创建两个外键列,而不是只有一个:

  • StreamWorkerUser_Id(我只想要这个专栏)
  • StreamWorkerUser_Id1

配置类配置如下:

AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;

我正在使用 Microsoft.Identity 框架,为所有模型提供自定义类。

我的 DbContext 类如下所示。

public class StreamWorkerDataContext : IdentityDbContext<StreamWorkerUser, StreamWorkerRole, int, StreamWorkerUserLogin, StreamWorkerUserRole, StreamWorkerUserClaim>
{
    public DbSet<Task> Tasks { get; set; }
}

Task 模型:

public class Task : StreamWorkerEntity
{
    public StreamWorkerUser StreamWorkerUser { get; set; }
}

StreamWorkerUser 模型:

public class StreamWorkerUser : IdentityUser<int, StreamWorkerUserLogin, StreamWorkerUserRole, StreamWorkerUserClaim>
    {
        public virtual List<Task> Tasks { get; set; } // also tested ICollection
    }

Task 类继承自这个基类型,这里也定义了StreamWorkerUser 类型的两个属性(但是这些列在数据库中正确生成。):

public class StreamWorkerEntity
{
    [Key]
    public int Id { get; set; }
    public DateTimeOffset Created { get; set; }
    public DateTimeOffset Updated { get; set; }
    public StreamWorkerUser Creator { get; set; }
    public StreamWorkerUser LastEditor { get; set; }
}

有没有可能是CreatorLastEditor属性干扰了数据库迁移?

我是否正确理解了约定?

更多信息:

  • 实体框架版本 6.1.3
  • Microsoft.AspNet.Identity.Core 2.2.1
  • Microsoft.AspNet.Identity.EntityFramework 2.2.1
  • ASP.NET 4 MVC 5
  • Azure 云中的 SQL Server
  • C# 6.0
  • .NET Framework 4.5.2
  • 所有这些代码都在类库中

【问题讨论】:

  • 如果您只需要一个外键,您希望如何存储与 Creator 和 LastEditor 的关系?
  • @faint220 我不想要一个外键。应该有三个。一种用于Creator,一种用于LastEditor,另一种用于StreamWorkerUser。目前生成了 4 列:Creator_Id、LastEditor_Id、StreamWorkerUser_Id、StreamWorkerUser_Id1。
  • 你试过实体类型配置吗???您可以使用 fluent api 显式声明外键
  • 我遇到了问题。你的任务有一个 StreamWorkerUser,它也继承自 StreamWorkerEntity,它有另一个 StreamWorkerUser 类型的字段。总而言之,StreamWorkerUser 有很多任务,而任务有 2 个用户(从数据库的角度来看,这算作很多)。您的关系似乎是多:多而不是 1:多。命名约定不关心关系逻辑的正确性。重新分析你的类和关系的概念。
  • 看看我在这里发布的答案:stackoverflow.com/questions/59465609/…

标签: c# sql-server asp.net-mvc entity-framework asp.net-identity


【解决方案1】:

所以你可能会认为 EF 在这种情况下:

 public StreamWorkerUser Creator { get; set; }
 public StreamWorkerUser LastEditor { get; set; }

将创建 creator_id 和 lasteditor_id,但它不会,因为 EF 使用了类名并创建了 StreamWorkerUser_Id 和 StreamWorkerUser_Id1,因为已经使用了 StreamWorkerUser_Id。默认情况下,如果按类(而不是 int 字段)建立关系,EF 根据类名(而不是字段名)生成其列名。

如果您想为这些 FK 指定列名,您可以这样做:

    public int CreatorId { get; set; } //this field name will be column name
    [ForeignKey("StreamWorkerUser")]
    public StreamWorkerUser Creator { get; set; }

    public int EditorId { get; set; } //this field name will also be column name
    [ForeignKey("StreamWorkerUser")]
    public StreamWorkerUser Editor { get; set; }

【讨论】:

  • 感谢您的回答,但在我的情况下,列名是从字段名生成的。请参阅问题下的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多