ASP.NET 核心 - Entity Framework 核心 - 下拉列表 - DbContext SaveChanges 问题

ASP.NET Core - Entity Framework Core - Drop Down List - DbContext SaveChanges Issue

我刚开始使用 EF 以及 ASP.NET Core。我正在开发一个简单的 Web 应用程序,但在保存新记录时出现错误。当 DbContext.SaveChanges() 被调用时,我收到一条错误消息:

“当 IDENTITY_INSERT 设置为 OFF 时,无法在 table 'ContactTypes' 中为标识列插入显式值。”

我完全理解消息的含义以及收到消息的原因。根据该消息,EF 正在尝试将记录插入到 ContactTypes table 中,并且由于 table 不允许插入主键值,因此会出现该错误。 ContactTypes table 有一组可能不会更改的固定记录。来自 ContactTypes table 的记录用于填充下拉列表(HTML select 元素)。该功能运行良好,当用户 select 选择所需的选项,然后尝试保存父(客户端)记录时,EF 想要将新记录插入 ContactTypes table,这是不必要的。当 EF Core 创建数据库时,“ContactTypeID”字段被添加到客户端 table,它应该包含 ContactType selected.

的 ID

下面是我的类

public class Client
{
    public int ID { get; set; }

    public Person Person { get; set; }// = new Person();
    public ContactType ContactType { get; set; }// = new ContactType();//Client or Inquiry

    //other properties removed for brevity
}

public class ContactType
{
    public int ID { get; set; }

    [StringLength(20)]
    public string ContactTypeDescription { get; set; } //typically either Client or Inquiry
}

public class Person
{
    public int ID { get; set; }

    [Required, StringLength(50)]
    public string FirstName { get; set; } = "N/A";

    [Required, StringLength(50)]
    public string LastName { get; set; } = "N/A";

    //other properties removed for brevity

}   

这是我的 OnModelCreating 方法:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        //setup our relationships
        modelBuilder.Entity<Client>()
            .HasOne(c => c.Person);

        modelBuilder.Entity<Client>()
            .HasOne(c => c.ContactType)
            .WithMany();


        //create our other supporting tables and initialize data if necessary
        modelBuilder.Entity<Person>().ToTable("People");

        modelBuilder.Entity<Person>().HasData(new Person { ID = 1, FirstName = "N/A", LastName = "N/A" });


        modelBuilder.Entity<ContactType>()
                    .ToTable("ContactTypes"); 

        modelBuilder.Entity<ContactType>().HasData(new ContactType { ID = 1, ContactTypeDescription = "Not Specified" },
                                                    new ContactType { ID = 2, ContactTypeDescription = "Inquiry" },
                                                    new ContactType { ID = 3, ContactTypeDescription = "Client" });

    }

这是我对 HTML select

的标记
<div class="col-sm-3">
    <label for="type" class="form-label stacked-justify-left">Contact Type</label>

    <select asp-for="Client.ContactType.ID" asp-items="Model.ContactTypes" class="form-control" style="height:40px; width:180px">
        <option value="">-- Select Type --</option>
    </select>
    <span asp-validation-for="Client.ContactType.ID" class="text-danger font-weight-bold"></span>
</div>

所以我不确定如何告诉 EF Core 在保存客户端实体信息时不要将记录添加到 ContactTypes table。如果需要其他信息,请询问,我会提供。感谢任何帮助。

大概Clientclass应该是:

public class Client
{
    public int ID { get; set; }

    public Person Person { get; set; }// = new Person();

    public int ContactTypeID { get; set; }

    public ContactType ContactType { get; set; }// = new ContactType();//Client or Inquiry
}

public class ContactType
{
    public int ID { get; set; }

    [StringLength(20)]
    public string ContactTypeDescription { get; set; } //typically either Client or Inquiry

    public IList<Client> Clients { get; set; }
}
modelBuilder.Entity<Client>()
            .HasOne(c => c.ContactType)
            .WithMany()
            .HasForeignKey(c => c.ContactTypeId);

并将视图修改为:

<select asp-for="Client.ContactTypeID" asp-items="Model.ContactTypes" class="form-control" style="height:40px; width:180px">
    <option value="">-- Select Type --</option>
</select>
<span asp-validation-for="Client.ContactTypeID" class="text-danger font-weight-bold"></span>

参考

  1. Conventions in Entity Framework Core
  2. One-to-Many Relationship Conventions in Entity Framework Core