C# 理解实体框架';这是多对多的关系。为什么我的代码在尝试添加更多数据时会崩溃?
我正在尝试创建一个联接表,该表结合了Employee表和Tractor表,以记录员工每次分配/取消分配卡车的情况。我可以记录最初的employeeID和truckId,但一旦我尝试在不同的时间和日期记录employeeID和truckId的第二个,代码就会崩溃。因此,Datetime对象始终是唯一的 这是它显示的错误: SqlException:违反主键约束“PK_DriverTractorsAssignmentHistory”。无法在对象“dbo.drivertractorssignmentHistory”中插入重复的密钥。重复的键值为(1,2)。 声明已终止 使用多对多关系是我能想到的一种解决方案,它可以在每次为员工分配卡车时捕获数据。如果你有更好的解决方案,请告诉我C# 理解实体框架';这是多对多的关系。为什么我的代码在尝试添加更多数据时会崩溃?,c#,asp.net-core,many-to-many,entity-framework-core,C#,Asp.net Core,Many To Many,Entity Framework Core,我正在尝试创建一个联接表,该表结合了Employee表和Tractor表,以记录员工每次分配/取消分配卡车的情况。我可以记录最初的employeeID和truckId,但一旦我尝试在不同的时间和日期记录employeeID和truckId的第二个,代码就会崩溃。因此,Datetime对象始终是唯一的 这是它显示的错误: SqlException:违反主键约束“PK_DriverTractorsAssignmentHistory”。无法在对象“dbo.drivertractorssignmentH
public class Employee
{
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public int? TractorID { get; set; }
public virtual Tractor Tractor { get; set; }
public virtual List<DriverTractorAssignmentHistory>DriverTractorAssignmentHistories { get; set; }
}
public class Tractor
{
public int TractorID { get; set; }
public string TruckNumber {get; set;}
public string Status { get; set; }
public virtual Employee Employee { get; set; }
public virtual List<DriverTractorAssignmentHistory> DriverTractorAssignmentHistories { get; set; }
public Tractor()
{
Status = "Available";
}
}
public class TrailerOrderDbContext:DbContext
{
public DbSet<Employee> Employees { get; set; }
public DbSet<DriverTractorAssignmentHistory> DriverTractorsAssignmentHistory { get; set; }
public DbSet<Tractor> Tractors { get; set; }
public TrailerOrderDbContext(DbContextOptions<TrailerOrderDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DriverTractorAssignmentHistory>().HasKey(co => new { co.EmployeeId, co.TractorId });
modelBuilder.Entity<DriverTractorAssignmentHistory>()
.HasOne(e => e.Driver)
.WithMany(c => c.DriverTractorAssignmentHistories)
.HasForeignKey(trac => trac.TractorId);
modelBuilder.Entity<DriverTractorAssignmentHistory>()
.HasOne(trac => trac.Tractor)
.WithMany(c => c.DriverTractorAssignmentHistories)
.HasForeignKey(e => e.EmployeeId);
}
}
公共类员工
{
public int EmployeeID{get;set;}
公共字符串名{get;set;}
公共字符串MiddleName{get;set;}
公共字符串LastName{get;set;}
公共int?TractorID{get;set;}
公共虚拟拖拉机{get;set;}
公共虚拟ListDriverTractorAssignmentHistories{get;set;}
}
公营拖拉机
{
公共int TractorID{get;set;}
公共字符串TruckNumber{get;set;}
公共字符串状态{get;set;}
公共虚拟员工{get;set;}
公共虚拟列表驱动器ractorassignmenthistories{get;set;}
公共拖拉机()
{
Status=“可用”;
}
}
公共类TrailerOrderDbContext:DbContext
{
公共数据库集雇员{get;set;}
公共数据库集驱动器TractorsAssignmentHistory{get;set;}
公共数据库集{get;set;}
公共TrailerOrderDbContext(DbContextOptions选项)
:基本(选项)
{
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity().HasKey(co=>new{co.EmployeeId,co.TractorId});
modelBuilder.Entity()
.HasOne(e=>e.Driver)
.WithMany(c=>c.DriverTractorAssignmentHistory)
.HasForeignKey(trac=>trac.TractorId);
modelBuilder.Entity()
.HasOne(trac=>trac.Tractor)
.WithMany(c=>c.DriverTractorAssignmentHistory)
.HasForeignKey(e=>e.EmployeeId);
}
}
在onmodellcreating(ModelBuilder-ModelBuilder)
中删除这一行代码,因为这一行代码可以防止重复数据输入,并防止多对多映射:
modelBuilder.Entity<DriverTractorAssignmentHistory>()
.HasKey(co => new { co.EmployeeId, co.TractorId });
虽然这解决了错误,但我认为这不是一个好答案。OP应该定义一个唯一键,这意味着它还应该包含添加该键的日期时间。要创建唯一键,您可以参考此链接
https://stackoverflow.com/questions/18889218/unique-key-constraints-for-multiple-columns-in-entity-framework
。但是在这种情况下,唯一键
应该是多个列的组合。我的建议是将EmployeeId
和TractorId`作为唯一键。EmployeeId和TractorId在DriverTractorAssignmentHistory
中必须是唯一的,因为它们是键的一部分,但它们不够唯一,因为OP每天可以多次分配/取消分配拖拉机的员工,所以它将失败。他需要的是另一个领域,使其独一无二。So`.HasKey(co=>new{co.EmployeeId,co.TractorId,co.AssignTimestamp}@谢谢。根据您的建议修改了我的答案。在DriverTractorAssignmentHistory上创建一个DateTime字段,并使其成为键的一部分,因此插入时这三个字段的组合应该是唯一的。您能否向我们展示DriverTractorAssignmentHistory
类的代码?
modelBuilder.Entity<DriverTractorAssignmentHistory>()
.HasKey(co => new { co.EmployeeId, co.TractorId, co.AssignTimestamp };