C# ASP.Net MVC插入时出现重复密钥异常
尝试将订单插入数据库时,我遇到一个奇怪的重复密钥异常。订单具有将用户与订单关联的用户关系 我不确定为什么会发生重复异常,因为我正在从DB抓取一个用户,然后在插入之前将其分配给订单 我的用户上下文只是用户的IRepository 信息C# ASP.Net MVC插入时出现重复密钥异常,c#,asp.net,entity-framework,model-view-controller,C#,Asp.net,Entity Framework,Model View Controller,尝试将订单插入数据库时,我遇到一个奇怪的重复密钥异常。订单具有将用户与订单关联的用户关系 我不确定为什么会发生重复异常,因为我正在从DB抓取一个用户,然后在插入之前将其分配给订单 我的用户上下文只是用户的IRepository 信息 使用EF版本6.2.0 Ctor public OrderManagerController(IRepository<Order> orderContext, IRepository<User> userContext)
- 使用EF版本6.2.0
public OrderManagerController(IRepository<Order> orderContext,
IRepository<User> userContext)
{
_orderContext = orderContext;
userContext = userContext;
}
public class Order : BaseEntity
{
[RegularExpression(@"^([0-9]{8})$", ErrorMessage = "Sales order number must be 8 digits.")]
[DisplayName("Sales Order Number")]
[Range(10000000,99999999)]
public int SalesOrderNumber { get; set; }
[DisplayName("Engineer Line Type")]
[Range(1,3)]
public int LineType { get; set; }
[Range(0,120)]
[DisplayName("Engineering Hours")]
public int EngineeringHours { get; set; }
[Range(0, 120)]
[DisplayName("Drafting Hours")]
public int DraftingHours { get; set; }
[Range(0, 240)]
[DisplayName("Estimated Hours")]
public int EstimatedHours { get; set; }
[StringLength(50)]
[DisplayName("Customer Name")]
public string CustomerName { get; set; }
[Range(0,2000000)]
[DisplayName("Order Total")]
public decimal OrderTotal { get; set; }
[StringLength(2)]
[DisplayName("PA/SB")]
public string Category { get; set; }
[DisplayName("Check Out Time")]
public DateTime? CheckedOutDate { get; set; }
[Required]
public User AssignedUser { get; set; }
[DisplayName("Scheduled Date Out")]
public DateTime? ScheduledCompletionDate { get; set; }
[Display(Name = "Out Date")]
public DateTime OutDate { get; set; }
[DisplayName("Actual Date Out")]
public DateTime? ActualCompletionDate { get; set; }
[StringLength(500)]
public string Comments { get; set; }
}
OrderManagerViewModel
public class OrderManagerViewModel
{
[RegularExpression(@"^([0-9]{8})$", ErrorMessage = "Sales order number must be 8 digits.")]
[DisplayName("Sales Order Number")]
[Range(10000000, 99999999)]
public int SalesOrderNumber { get; set; }
[DisplayName("Engineer Line Type")]
[Range(1, 3)]
public int LineType { get; set; }
[Range(0, 240)]
[DisplayName("Estimated Hours")]
public int EstimatedHours { get; set; }
[StringLength(50)]
[DisplayName("Customer Name")]
public string CustomerName { get; set; }
[Range(0, 2000000)]
[DisplayName("Order Total")]
public decimal OrderTotal { get; set; }
[StringLength(2)]
[DisplayName("PA/SB")]
public string Category { get; set; }
public string FirstName { get; set; }
public string AssignedUserId { get; set; }
[DisplayName("Scheduled Date Out")]
public DateTime? ScheduledCompletionDate { get; set; }
[Display(Name = "Out Date")]
public DateTime OutDate { get; set; }
[StringLength(500)]
public string Comments { get; set; }
}
订单
public OrderManagerController(IRepository<Order> orderContext,
IRepository<User> userContext)
{
_orderContext = orderContext;
userContext = userContext;
}
public class Order : BaseEntity
{
[RegularExpression(@"^([0-9]{8})$", ErrorMessage = "Sales order number must be 8 digits.")]
[DisplayName("Sales Order Number")]
[Range(10000000,99999999)]
public int SalesOrderNumber { get; set; }
[DisplayName("Engineer Line Type")]
[Range(1,3)]
public int LineType { get; set; }
[Range(0,120)]
[DisplayName("Engineering Hours")]
public int EngineeringHours { get; set; }
[Range(0, 120)]
[DisplayName("Drafting Hours")]
public int DraftingHours { get; set; }
[Range(0, 240)]
[DisplayName("Estimated Hours")]
public int EstimatedHours { get; set; }
[StringLength(50)]
[DisplayName("Customer Name")]
public string CustomerName { get; set; }
[Range(0,2000000)]
[DisplayName("Order Total")]
public decimal OrderTotal { get; set; }
[StringLength(2)]
[DisplayName("PA/SB")]
public string Category { get; set; }
[DisplayName("Check Out Time")]
public DateTime? CheckedOutDate { get; set; }
[Required]
public User AssignedUser { get; set; }
[DisplayName("Scheduled Date Out")]
public DateTime? ScheduledCompletionDate { get; set; }
[Display(Name = "Out Date")]
public DateTime OutDate { get; set; }
[DisplayName("Actual Date Out")]
public DateTime? ActualCompletionDate { get; set; }
[StringLength(500)]
public string Comments { get; set; }
}
基本实体
public abstract class BaseEntity
{
public string Id { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public BaseEntity()
{
Id = Guid.NewGuid().ToString();
CreatedAt = DateTime.Now;
}
}
i积极实施
[HttpPost]
public ActionResult Create(OrderManagerViewModel order)
{
if (!ModelState.IsValid)
return View("Create", order);
else
{
User user = _userContext.Find(order.AssignedUserId); // Grab user from DB
//Create the order from the passed in view model and DB user
Order orderToInsert = new Order
{
AssignedUser = user,
Category = order.Category,
Comments = order.Comments,
CustomerName = order.CustomerName,
EstimatedHours = order.EstimatedHours,
SalesOrderNumber = order.SalesOrderNumber,
LineType = order.LineType,
OrderTotal = order.OrderTotal,
ScheduledCompletionDate = order.ScheduledCompletionDate,
OutDate = order.OutDate
};
_orderContext.Insert(orderToInsert); // Insert
_orderContext.Commit();//Save -----Crashes with Duplicate Exception on AssignedUser.Id
return RedirectToAction("Index");
}
}
public class SQLRepository<T> : IRepository<T> where T : BaseEntity
{
internal DataContext context;
internal DbSet<T> dbSet;
public SQLRepository(DataContext context)
{
this.context = context;
dbSet = context.Set<T>();
}
public IQueryable<T> Collection()
{
return dbSet;
}
public void Commit()
{
context.SaveChanges();
}
public void Delete(string Id)
{
var t = Find(Id);
if (context.Entry(t).State == EntityState.Detached)
dbSet.Attach(t);
dbSet.Remove(t);
}
public T Find(string Id)
{
return dbSet.Find(Id);
}
public void Insert(T t)
{
dbSet.Add(t);
}
public void Update(T t)
{
dbSet.Attach(t);
context.Entry(t).State = EntityState.Modified;
}
}
public类SQLRepository:IRepository其中T:BaseEntity
{
内部数据上下文;
内部数据库集;
公共SQLRepository(DataContext上下文)
{
this.context=上下文;
dbSet=context.Set();
}
公共IQueryable集合()
{
返回dbSet;
}
公共无效提交()
{
SaveChanges();
}
公共无效删除(字符串Id)
{
var t=查找(Id);
if(context.Entry(t.State==EntityState.Distached)
dbSet.Attach(t);
dbSet.Remove(t);
}
公共找不到(字符串Id)
{
返回dbSet.Find(Id);
}
公共空白插入(T)
{
dbSet.Add(t);
}
公共无效更新(T)
{
dbSet.Attach(t);
context.Entry(t).State=EntityState.Modified;
}
}
不确定我是否误解了某些内容。问题似乎是因为您的用户和订单来自不同的上下文……我看不出您在ninject中注册DbContext的位置,但您希望确保注册它。这将确保您在一个请求中为所有操作获得相同的上下文。订单表上的主键是什么?@Harry主键是从BaseEntity继承的。@Harry也只是提一下。它不会在orders主键上崩溃,而是在插入时在分配给用户的主键上崩溃。我已经调试并验证了我查询的用户实际上正在从数据库返回一个用户。然后我分配它,插入,然后它在分配的用户ID上崩溃。我已经多年没有使用.NET了。我相信用户是持久化的,您可以通过将objectTrackingEnabled设置为false来避免用户被持久化,因为您是从不同的上下文加载用户。就OrderContext而言,该用户是“新用户”。从OrderContext而不是UserContext加载用户。有界上下文不应“共享”实体。你可以,通过将用户附加到OrderContext,但是你首先需要检查OrderContext的本地,看看它是否还“知道”该用户。你我的朋友太棒了。谢谢你的建议。我在请求范围内的ninject中注册了我的上下文,它成功了!