迁移会创建意外的 ID 字段,但未明确指定
Posted
技术标签:
【中文标题】迁移会创建意外的 ID 字段,但未明确指定【英文标题】:Migration creates unexpected ID field, though not explicitly specified 【发布时间】:2019-06-07 08:38:27 【问题描述】:C# Code First 迁移会创建额外的字段,即 [WebsiteUser_UserID] [int]
,但未明确指定。
我在引用父类字段[WebsiteUser].[UserID]
的子类(LessonComment
) 中创建了一些属性,例如PostedBy
和CensoredBy
。但是,当我运行命令 Update-database -script
时,它会在子类中创建一个字段 [WebsiteUser_UserID]
。
WebsiteUser.cs
public partial class WebsiteUser
public WebsiteUser()
this.Courses = new List<Course>();
this.LessonComments = new List<LessonComment>();
this.UserLessons = new List<UserAssessLesson>();
[Key]
public int UserID get; set;
[Required]
public string Name get; set;
[Required]
public string Email get; set;
[MaxLength(200)]
[Required]
[ScaffoldColumn(false)]
public string PasswordHash get; set;
[ForeignKey("Role")]
public Nullable<int> RoleID get; set;
public virtual Role Role get; set;
public virtual ICollection<Course> Courses get; set; // New
public virtual ICollection<LessonComment> LessonComments get; set;
public virtual ICollection<UserAssessLesson> UserLessons get; set;
LessonComment.cs
public partial class LessonComment
[Key]
public int CommentID get; set;
[MaxLength(500)]
public string Comment get; set;
[ForeignKey("CourseLesson")]
public int LessonID get; set;
[ForeignKey("PostedBy")]
public int PostedByUserID get; set;
public DateTime DatePosted get; set;
// CENSORSHIP DETAIL (If comment is censored)
public Nullable<bool> IsCensored get; set; // Comment will not be displayed until verified
[ForeignKey("CensoredBy")]
public int CensoredByUserID get; set;
public Nullable<DateTime> CensorDate get; set;
[MaxLength(100)]
public string CensorReason get; set;
// Navigation Properties
public virtual CourseLesson CourseLesson get; set;
public virtual WebsiteUser PostedBy get; set;
public virtual WebsiteUser CensoredBy get; set;
SQL 脚本
CREATE TABLE [dbo].[WebsiteUser] (
[UserID] [int] NOT NULL IDENTITY,
[Name] [nvarchar](max) NOT NULL,
[Email] [nvarchar](max) NOT NULL,
[PasswordHash] [nvarchar](200) NOT NULL,
[RoleID] [int],
CONSTRAINT [PK_dbo.WebsiteUser] PRIMARY KEY ([UserID])
)
CREATE TABLE [dbo].[LessonComment] (
[CommentID] [int] NOT NULL IDENTITY,
[Comment] [nvarchar](500),
[LessonID] [int] NOT NULL,
[PostedByUserID] [int] NOT NULL,
[DatePosted] [datetime] NOT NULL,
[Censored] [bit],
[CensoredByUserID] [int] NOT NULL,
[CensorDate] [datetime],
[CensorReason] [nvarchar](100),
[WebsiteUser_UserID] [int], -- How is this created ???
CONSTRAINT [PK_dbo.LessonComment] PRIMARY KEY ([CommentID])
)
CREATE INDEX [IX_LessonID] ON [dbo].[LessonComment]([LessonID])
CREATE INDEX [IX_PostedByUserID] ON [dbo].[LessonComment]([PostedByUserID])
CREATE INDEX [IX_CensoredByUserID] ON [dbo].[LessonComment]([CensoredByUserID])
CREATE INDEX [IX_WebsiteUser_UserID] ON [dbo].[LessonComment]([WebsiteUser_UserID])
ALTER TABLE [dbo].[LessonComment] ADD CONSTRAINT [FK_dbo.LessonComment_dbo.WebsiteUser_CensoredByUserID] FOREIGN KEY ([CensoredByUserID]) REFERENCES [dbo].[WebsiteUser] ([UserID]) ON DELETE CASCADE
ALTER TABLE [dbo].[LessonComment] ADD CONSTRAINT [FK_dbo.LessonComment_dbo.CourseLesson_LessonID] FOREIGN KEY ([LessonID]) REFERENCES [dbo].[CourseLesson] ([LessonID]) ON DELETE CASCADE
ALTER TABLE [dbo].[LessonComment] ADD CONSTRAINT [FK_dbo.LessonComment_dbo.WebsiteUser_PostedByUserID] FOREIGN KEY ([PostedByUserID]) REFERENCES [dbo].[WebsiteUser] ([UserID]) ON DELETE CASCADE
ALTER TABLE [dbo].[LessonComment] ADD CONSTRAINT [FK_dbo.LessonComment_dbo.WebsiteUser_WebsiteUser_UserID] FOREIGN KEY ([WebsiteUser_UserID]) REFERENCES [dbo].[WebsiteUser] ([UserID]) --No idea how this is created
预期结果是不应创建附加字段“[WebsiteUser_UserID] [int]”。
【问题讨论】:
你的 DbContext 在哪里? 将[ForeignKey("PostedBy")]
更改为 [ForeignKey("PostedByUserID")]
并将其放在您的导航属性中,对其他人也这样做。
问题是用于将 ForeignKey 映射到父类的 enityframework 遵循与子类中的父类名称相同的名称的属性。将 PostedByUserID 更改为 WebsiteUserId 或使用 fluent api 进行地图
阿明这不是解决方案。我应该将PostedByUserID
和CensoredByUserID
都更改为WebsiteUserID
;因为它们引用的是 WebsiteUser 类。一个类可以有 2 个名称完全相同的属性吗?
奥尔德特,我试过很多次;你没有时间尝试吗?定义导航有 3 种方法 1 public int PostedByUserID get; set; [ForeignKey("PostedByUserID")] public virtual WebsiteUser PostedBy get; set;
2 [ForeignKey("PostedBy")] public int PostedByUserID get; set; public virtual WebsiteUser PostedBy get; set;
在在实体框架中定义外键的方法下阅读this 我发现了这个问题并回答了我自己的问题
【参考方案1】:
使用父类中的InverseProperty
注解解决:
public partial class WebsiteUser
// ...
[InverseProperty("PostedBy")] // Solved the problem
public virtual ICollection<LessonComment> LessonComments get; set;
注意:由于子类中有超过 1 个外键(PostedBy、CensoredBy),因此需要在父类。
阅读以下[文章](http://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in-code-first.aspx"InverseProperty-Data Annotations-attribute-in-code-first")
【讨论】:
以上是关于迁移会创建意外的 ID 字段,但未明确指定的主要内容,如果未能解决你的问题,请参考以下文章
在 Codeigniter DBForge 迁移中创建唯一字段