ASP.NET MVC5 - 更新数据库后创建不需要的字段

Posted

技术标签:

【中文标题】ASP.NET MVC5 - 更新数据库后创建不需要的字段【英文标题】:ASP.NET MVC5 - unwanted field created after update database 【发布时间】:2017-02-19 01:33:47 【问题描述】:

我正在尝试在“ApplicationUser”类和最近创建的“Issue”类之间创建“一对多”关系。

所以,在 Models / IdentityModels.cs / ApplicationUser 我添加了这个属性:

public ICollection<Issue> Issues  get; set; 

Issue.cs 有这个代码:

namespace Test.Models

    public class Issue
    
        public int Id  get; set; 
        public ApplicationUser Courier  get; set; 
        public ApplicationUser Customer  get; set; 
    

我正在使用自动迁移。因此,在构建并运行“update-database”之后,问题表已创建,其中包含以下字段:

    身份证 ApplicationUser_Id CourierId 客户 ID

我的问题是为什么会创建“ApplicationUser_Id”字段以及如何防止它?

【问题讨论】:

添加属性的目的是什么?它应该包含什么 - 用户是 Courier 还是 Customer 的问题? 您是否使用过 Code First 迁移架构?可能您需要在 PK 字段上设置 KeyAttribute 以保留定义的主键并在执行迁移之前创建表关系。 【参考方案1】:

问题在于 EF 认为您实际上需要 Issue 和 ApplicationUser 之间的三个一对多关系:

一个用于ICollection&lt;Issue&gt; Issues 上的ApplicationUser (ApplicationUser_Id) ApplicationUser CourierIssue (CourierId) 上的一个 一个用于ApplicationUser CustomerIssue (CustomerId)

(请注意,EF 允许从任一方定义关系。)

如果您希望ApplicationUser.Issues 包含此用户的所有问题,无论他是快递员还是客户,您都需要额外的 ApplicationUser_Id 键。配置 EF 以使其正常工作将非常痛苦。

也许有一个更简单的解决方案:在ApplicationUser 上引入两个集合。

public ICollection<Issue> CourierIssues  get; set; 
public ICollection<Issue> CustomerIssues  get; set; 

然后在ModelBuilder中使用fluent API配置反向链接,消除ApplicationUser_Id键:

 modelBuilder.Entity<ApplicationUser>().HasMany(au => au.CourierIssues).WithOptional(i => i.Courier);
 modelBuilder.Entity<ApplicationUser>().HasMany(au => au.CustomerIssues).WithOptional(i => i.Customer);

【讨论】:

【参考方案2】:

因为ApplicationUserCourierCustomer 有两个外键,但ApplicationUser 上只有一个引用Issue 的集合。 EF 无法知道它应该与哪个外键对齐,所以它只是创建了一个新的。要正确处理此问题,您需要使用 fluent 配置:

public class ApplicationUser

    ...

    public class Mapping : EntityTypeConfiguration<ApplicationUser>
    
        HasMany(m => m.Issues).WithRequired(m => m.Customer);
    

那么,在你的上下文中:

protected override void OnModelCreating(DbModelBuilder modelBuilder)

    base.OnModelCreating(modelBuilder);

    modelBuilder.Configurations.Add(new ApplicationUser.Mapping());

当然,这里的问题是您可能想要跟踪 CustomerCourier 集合的集合。为此,您需要 两个 集合:

public virtual ICollection<Issue> CustomerIssues  get; set; 
public virtual ICollection<Issue> CourierIssues  get; set; 

然后,如下流畅的配置:

HasMany(m => m.CustomerIssues).WithRequired(m => m.Customer);
HasMany(m => m.CourierIssues).WithRequired(m => m.Courier);

【讨论】:

以上是关于ASP.NET MVC5 - 更新数据库后创建不需要的字段的主要内容,如果未能解决你的问题,请参考以下文章

保存数据库控制器类 asp.net mvc5 身份中的更改

Entity Framework的学习(ASP.NET MVC5的学习中的一部分)

使用 2 个表实现 ASP.NET MVC5 搜索功能

ASP.NET MVC5+EF6搭建三层实例

ASP.NET + MVC5 入门完整教程三 (上) ---第一个MVC项目

C# 程序员编程 ASP.NET CORE MVC5 EF Redis 多线程 异步 爬虫 视频教程