Исключение дублирующегося ключа ASP.Net MVC при вставке - PullRequest
0 голосов
/ 03 апреля 2019

При попытке вставить свой заказ в базу данных я получаю странное исключение дублированного ключа. В заказе есть отношение пользователя, которое связывает пользователя с заказом.

Я не уверен, почему возникает двойное исключение, когда я беру пользователя из БД и затем назначаю его заказу перед вставкой.

Мой пользовательский контекст - это просто IRepository пользователя.

информация

  • Использование EF версии 6.2.0

CTOR

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

Ninject Binding

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

Реализация репозитория

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 Ответ

1 голос
/ 03 апреля 2019

Похоже, проблема в том, что ваш пользователь и заказ происходят из разных контекстов ... Я не вижу, где вы регистрируете свой DbContext в ninject, но вы хотите убедиться, что вы зарегистрировали его в запросесфера .Это обеспечит получение одинакового контекста для всех операций в рамках одного запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...