【发布时间】:2022-11-19 01:23:39
【问题描述】:
尝试创建类型为 TestForm2 的新数据库条目时,我将相关对象单元类型的 ID 作为外键包含在内,除非我在添加新模型后执行 context.SaveChanges() 时出现以下 SQL 异常:
SqlException:违反 PRIMARY KEY 约束“PK_dbo.UnitTypes”。无法在对象“dbo.UnitTypes”中插入重复键。重复键值为 (2d911331-6083-4bba-a3ad-e50341a7b128)。该语句已终止。
这对我来说意味着它认为我试图与新模型关联的外部条目是一个新对象,它试图插入到 UnitTypes 表中但失败了,因为它看到一个具有相同主键的现有条目.
对于上下文(双关语不是故意的),这是我的数据上下文、数据库模型和错误的“创建”函数。
public class DataContext : IdentityDbContext<ApplicationUser> { public DataContext() : base("DefaultConnection") { } public static DataContext Create() { return new DataContext(); } public DbSet<SafetyIncident> SafetyIncidents { get; set; } public DbSet<ProductionLine> ProductionLines { get; set; } public DbSet<ProductionOrder> ProductionOrders { get; set; } public DbSet<SerialOrder> SerialOrder { get; set; } public DbSet<QualityError> QualityErrors { get; set; } public DbSet<PSA> PSAs { get; set; } public DbSet<TestStation> TestStations { get; set; } public DbSet<ProductionGoal> ProductionGoals { get; set; } public DbSet<DailyWorkStationCheck> DailyWorkStationChecks { get; set; } public DbSet<TestForm> TestForms { get; set; } public DbSet<User> AppUsers { get; set; } public DbSet<Options> Options { get; set; } public DbSet<DriveList> DriveSerials { get; set; } public DbSet<MRPController> MRPControllers { get; set; } public DbSet<TestOption> TestOptions { get; set; } public DbSet<UnitType> UnitTypes { get; set; } public DbSet<UnitTypeMap> UnitTypeMaps { get; set; } public DbSet<TestForm2> TestForm2s { get; set; } public DbSet<TestFormSection> TestFormSections { get; set; } public DbSet<TestFormSectionStep> TestFormSectionSteps { get; set; } }public class TestForm2 : BaseEntity { public string SerialNumber { get; set; } public string MaterialNumber { get; set; } public string UnitTypeId { get; set; } public UnitType UnitType { get; set; } public bool UsesStandardOptions { get; set; } public bool OptionsVerified { get; set; } // This will only be used when UsesStandardOptions is true, otherwise its value doesn't matter public ICollection<TestOption> AllOptions { get; set; } // List of all options (at time of form creation) public ICollection<TestOption> Options { get; set; } // The options on a unit public ICollection<TestFormSection> Sections { get; set; } }public FormViewModel Create(FormViewModel vm) { using (var context = new DataContext()) { List<string> optionListStrings = GetOptionListForModelNumber(vm.MaterialNumber); // returns list of option codes List<TestOption> matchingOptions = context.TestOptions .Where(optionInDb => optionListStrings.Any(trimOption => trimOption == optionInDb.OptionCode)).ToList(); var unitType = context.UnitTypes.FirstOrDefault(x => x.Name == vm.UnitType); string unitTypeId = unitType.Id; TestForm2 newForm = new TestForm2 { // ID & CreatedAt instantiated by Base Entity constructor SerialNumber = vm.SerialNumber, MaterialNumber = vm.MaterialNumber, UnitTypeId = unitType.Id, UsesStandardOptions = vm.UsesStandardOptions, OptionsVerified = vm.OptionsVerified, //AllOptions = context.TestOptions.ToList(), //Options = matchingOptions, Sections = vm.Sections, }; context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s); context.TestForm2s.Add(newForm); context.SaveChanges(); // THIS IS WHERE THE SQL EXCEPTION IS HAPPENING return vm; } return null; }最后,我不确定它是否相关,但只有在 context.TestForm2s.add(newForm) 解析后,相关 UnitType 的完整副本才可作为 newForm 的一部分查看。这对我来说很奇怪,因为我认为它不应该像那样自动关联数据对象。
我没能尝试太多,因为对我来说一切看起来都配置正确。如果不是这种情况,或者我是否应该包含任何其他信息,请告诉我。
【问题讨论】:
-
你能说明你在哪里定义了外键关系吗?
-
@Andrew 外键是 UnitTypeId。在“Create”方法期间,从具有来自 FormViewModel (vm.UnitType) 的相同“Name”字段的适当的 UnitType 对象查询它。这是一个 link to an image 显示关系已正确定义。
标签: c# sql-server asp.net-mvc entity-framework