1

Каждый раз, когда я создаю новый PurchasedProduct и ссылаюсь на него Product, при вставке в таблицу таблица всегда создает новый идентичный Product и ссылается на новый один, а не ссылаться на существующий.Создание новой записи, приводящей к созданию идентичной новой записи в связанной таблице

Итак, у меня есть эти 3 соответствующие таблицы: enter image description here

..which означает, что Purchase может иметь много PurchasedProduct, каждый из которых представляет собой приобретенный Product и сколько его приобрели (Количество).

Это WinForm: enter image description here

Это соответствующие коды:

public partial class fmAddEditPurchase : Form 
{ 
    List<Product> products; 
    Purchase purchase; 

    public fmAddEditPurchase() 
    { 
     InitializeComponent(); 
     Purchase = new Purchase(); 
     Text = "Add New Purchase"; 
     dtpDate.Value = DateTime.Now.Date; 

     RefreshPurchasedProduct(); 
     LoadProductList(); 
    } 

    private void RefreshPurchasedProduct() 
    { 
     List<PurchasedProduct> ppQuery = new List<PurchasedProduct>(); 
     BindingSource bi = new BindingSource(); 

     if (Purchase.PurchasedProducts.Count > 0) 
     { 
      using (var context = new dbKrunchworkContext()) 
      { 
       bi.DataSource = Purchase.PurchasedProducts. 
        Join(products, x => x.Product, y => y, (x, y) => 
          new { y.Product_Name, x.Price, x.Quantity }). 
          ToList(); 
      } 
     } 

     dgvPurchasedProduct.DataSource = bi; 
     dgvPurchasedProduct.Refresh(); 
    } 

    private void LoadProductList() 
    { 
     using (var context = new dbKrunchworkContext()) 
     { 
      products = context.Products.ToList(); 
     } 

     cbProductName.DataSource = products. 
      Select(x => x.Product_Name).ToList(); 
    } 

    private void btAddProduct_Click(object sender, EventArgs e) 
    { 
     decimal price = 0.0M; 

     if (decimal.TryParse(tbPrice.Text, out price) && price > 0) 
     { 
      PurchasedProduct temp = Purchase.PurchasedProducts. 
       FirstOrDefault(
        x => x.Product == 
        products[cbProductName.SelectedIndex] && 
        x.Price == price); 

      if (temp == null) 
      { 
       PurchasedProduct newPP = new PurchasedProduct(); 

       newPP.Product = products[cbProductName.SelectedIndex]; 
       newPP.Purchase = Purchase; 
       newPP.Quantity = (int)numQuantity.Value; 
       newPP.Price = price; 

       if (newPP.Product != null) 
       { 
        Purchase.PurchasedProducts.Add(newPP); 
       } 
      } 
      else 
      { 
       temp.Quantity += (int)numQuantity.Value; 
      } 

      RefreshPurchasedProduct(); 
     } 
    } 

    private void btSave_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      Purchase.Received_Date = dtpDate.Value; 
      Purchase.Total_Amount = decimal.Parse(tbTotalPrice.Text); 
      Purchase.Note = tbNote.Text; 

      using (var context = new dbKrunchworkContext()) 
      { 
       for (int i = 0; i < Purchase.PurchasedProducts.Count; i++) 
       { 
        PurchasedProduct pp = 
         Purchase.PurchasedProducts.ElementAt(i); 

        Product p = context.Products. 
         FirstOrDefault(x => x.ID == pp.Product.ID); 

        pp.Product = p; 
       } 
      } 
     } 
     catch (Exception) 
     {     

     } 
    } 
} 

И это главная форма, вставить новую запись в таблицу после получения DialogResult() == DialogResult.OK сверху Form.

private void Purchase_AddNewRecord() 
    { 
     fmAddEditPurchase addForm = new fmAddEditPurchase(); 

     if (addForm.ShowDialog() == 
      DialogResult.OK && addForm.Purchase.Total_Amount > 0) 
     { 
      using (var context = new dbKrunchworkContext()) 
      { 
       context.Purchases.Add(addForm.Purchase); 
       context.SaveChanges(); 
      } 
     } 
    } 

Пример:

Перед

enter image description here

То, что я сделал (+ сохранить)

enter image description here

После (Обратите внимание, что создание нового Product вместо использования старого)

enter image description here

+0

Для лучшей поддержки, поскольку вы используете Windows Forms, просто создайте один экземпляр вашего контекста как поле вашей формы. Это лучше, а не склонность к ошибкам, как этот, который вы нам показываете. – CodeNotFound

+0

Это, похоже, происходит потому, что сущность 'Product' отделяется от контекста, в котором вы сохраняете' PurchaseProduct'. Сначала попробуйте подключить его, а затем используйте его как ссылку на объект 'BuyasedProduct'. –

ответ

1

Вы используете несколько экземпляров вашего DbContext в нескольких методах формы.

У вас возникла эта проблема, потому что приведенный ниже код примет все объекты в графе Purshase и отметит все их в Added состоянии.

private void Purchase_AddNewRecord() 
{ 
    fmAddEditPurchase addForm = new fmAddEditPurchase(); 

    if (addForm.ShowDialog() == 
     DialogResult.OK && addForm.Purchase.Total_Amount > 0) 
    { 
     using (var context = new dbKrunchworkContext()) 
     { 
      context.Purchases.Add(addForm.Purchase); 
      context.SaveChanges(); 
     } 
    } 
} 

Чтобы решить эту проблему вы должны изменить состояние каждого Product экземпляра связанного с Purshase например, как происходит некорректно код:

private void Purchase_AddNewRecord() 
{ 
    fmAddEditPurchase addForm = new fmAddEditPurchase(); 

    if (addForm.ShowDialog() == 
     DialogResult.OK && addForm.Purchase.Total_Amount > 0) 
    { 
     using (var context = new dbKrunchworkContext()) 
     { 
      context.Purchases.Add(addForm.Purchase); 
      foreach (var purchasedProduct in addForm.Purchase.PurchasedProducts) 
      { 
       context.Entry(purchasedProduct.Product).State = EntityState.Unchanged; 
      } 
      context.SaveChanges(); 
     } 
    } 
} 

Не рекомендуется, если вы используете Windows Forms или WPF, чтобы создайте новый экземпляр вашего DbContext в каждом методе, который вы на самом деле делаете. Вы должны создать только одну форму, создав для этого поле.

+0

Привет, спасибо, что ответили. Кстати, не можете ли вы немного подробнее пояснить «context.Entry (purchaseProduct.Product) .State = EntityState.Unchanged;'? Так как я не понимаю, как работает код. Благодарю. –

Смежные вопросы