插入时ASP.Net MVC复制密钥异常

时间:2019-04-02 21:50:45

标签: c# asp.net entity-framework model-view-controller

尝试将我的订单插入数据库时​​,我收到一个奇怪的重复键异常。订单具有与用户相关的用户关系。

我不确定为什么会发生重复异常,因为我正在从数据库中抓取一个用户,然后在插入之前将其分配给订单。

我的用户上下文只是用户的IRepository。

信息

  • 使用EF版本6.2.0

Cor

public OrderManagerController(IRepository<Order> orderContext,
        IRepository<User> userContext)
{
    _orderContext = orderContext;
     userContext = userContext;
}

插入绑定

private static IKernel CreateKernel()
{
    var kernel = new StandardKernel();
    try
    {
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        //Bind concrete classes to contracts
        kernel.Bind<IRepository<Order>>().To<SQLRepository<Order>>();
        kernel.Bind<IRepository<User>>().To<SQLRepository<User>>();
        RegisterServices(kernel);
        return kernel;
    }
    catch
    {
        kernel.Dispose();
        throw;
    }
}

操作

[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");
        }
    }

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

IRepository实施

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

不确定我是否误会了一些东西。

1 个答案:

答案 0 :(得分:1)

问题似乎是因为您的用户和订单来自不同的上下文...我看不到您在ninject中注册DbContext的位置,但是您想确保对其进行注册in request scope 。这样可以确保您在单个请求中为所有操作获得相同的上下文。