实体框架设置外键,主键冲突



当尝试创建类型为TestForm2的新数据库条目时,我包括相关对象Unit type的ID作为外键,除非当我在添加新模型后执行context.SaveChanges()时,我得到以下SQL异常:

SqlException:违反PRIMARY KEY约束'PK_dbo.UnitTypes'。不能在对象'dbo.UnitTypes'中插入重复键。重复键值为(2d911331-6083-4bba-a3ad-e50341a7b128)。语句已被终止。

这对我来说意味着它认为我试图与新模型相关的外部条目是一个新对象,它试图插入到UnitTypes表中并且失败,因为它看到一个具有相同主键的现有条目。

对于上下文(不打算双关语),这是我的数据上下文,数据库模型和错误的"Create"函数。

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;
}

最后,我不确定它是否相关,但是相关UnitType的完整副本只有在context.TestForm2s.add(newForm)解析后才能作为newForm的一部分查看。这对我来说很奇怪,因为我认为它不应该像那样自动关联数据对象。

我还没有能够尝试太多,因为一切看起来正确配置给我。如果情况并非如此,或者我是否应该包括任何其他信息,请让我知道。

找到问题。vm。section不是使用视图模型来包含节数据,因此vm。章节包含了UnitType数据库模型。由于这是在控制器中实例化的(在TestForm2 Create方法中打开数据上下文之前),EF假设这些数据是新的,需要添加到UnitType表中。

希望这个帖子能帮助到其他遇到类似问题的人。

最新更新