Заголовок Entity Framework, Ошибка сохранения детали - PullRequest
1 голос
/ 06 января 2020

Я новичок в Entity Framework, у меня проблема с заголовком Saving и подробными записями в многослойном приложении

Это мои классы моделей:

public class SalesOrderHeader
    {
        public SalesOrderHeader()
        {
            this.SalesPerson = new SalesPerson();
            this.Customer = new Customer();
        }
        public int Id { get; set; }
        //public int CustId { get; set; }
        public string CustName { get; set; }
        public string CustCity { get; set; }

        [Required]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
        public System.DateTime PostingDate { get; set; }

        [Required]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
        public System.DateTime OrderDate { get; set; }

        [Required]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
        public System.DateTime DocumentDate { get; set; }

        [Required]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
        public System.DateTime DeliveryDate { get; set; }

        public bool Status { get; set; }
        public decimal SoDiscountAmount { get; set; }
        public decimal SoTotal { get; set; }
        public decimal SoDiscount { get; set; }

        public virtual Customer Customer { get; set; }
        public virtual ICollection<SalesOrderDetail> SalesOrderDetails { get; set; }
        public virtual SalesPerson SalesPerson { get; set; }
    }

 public class SalesOrderDetail
    {
        public SalesOrderDetail()
        {
            this.Item = new Item();
            this.SalesOrderHeader = new SalesOrderHeader();
        }
        public int Id { get; set; }

        [ForeignKey("SalesOrderHeader")]
        public int? SoId { get; set; }

        public string ItemCode { get; set; }
        public string ItemDescription { get; set; }
        public string LocationCode { get; set; }
        public int Quantity { get; set; }
        public string UOM { get; set; }
        public decimal UnitPrice { get; set; }
        public decimal LineAmount { get; set; }
        public decimal LineDiscount { get; set; }

        public virtual Item Item { get; set; }
        public virtual SalesOrderHeader SalesOrderHeader { get; set; }

    }



public class Item
    {
        public Item()
        {
            this.UnitofMeasure = new UnitofMeasure();
            this.ItemCategory = new ItemCategory();
        }
        public int Id { get; set; }
        public string ItemCode { get; set; }
        public string ItemDescription { get; set; }
        public int StockQuantity { get; set; }
        public decimal UnitPrice { get; set; }

        //public int CategoryId { get; set; }
        public virtual ItemCategory ItemCategory { get; set; }

        //public int UOMId { get; set; }
        public virtual UnitofMeasure UnitofMeasure { get; set; }
        public virtual ICollection<SalesOrderDetail> SalesOrderDetails { get; set; }

    }


public class ItemCategory
    {
        public int Id { get; set; }
        public string CategoryName { get; set; }

        public virtual ICollection<Item> Items { get; set; }

    }
public class UnitofMeasure
{
    public int Id { get; set; }
    public string UOM { get; set; }

    public virtual ICollection<Item> Items { get; set; }

}

Form Code

private void GetUIDetailData(SalesOrderHeader h)
    {

        h.SalesOrderDetails = new List<SalesOrderDetail>();
        try
        {

            for (int i = 0; i < dgSODetails.Rows.Count - 1 ; i++)
            {
                SalesOrderDetail x = new SalesOrderDetail();

                //x.SalesOrderHeader.Id = h.Id;
                x.SalesOrderHeader = h;

                string _code = dgSODetails.Rows[i].Cells[1].Value.ToString();
                Item _item = _ItemShareMgr.LoadItemByCode(_code);


                x.Item.Id = _item.Id;


                x.ItemCode = _code;
                x.ItemDescription = dgSODetails.Rows[i].Cells[2].Value.ToString();
                x.LocationCode = dgSODetails.Rows[i].Cells[3].Value.ToString();
                x.Quantity = int.Parse(dgSODetails.Rows[i].Cells[4].Value.ToString());
                x.UOM = dgSODetails.Rows[i].Cells[5].Value.ToString();
                x.UnitPrice = decimal.Parse(dgSODetails.Rows[i].Cells[6].Value.ToString());
                //x.LineAmount = decimal.Parse(dgSODetails.Rows[i].Cells[8].Value.ToString());
                x.LineDiscount = decimal.Parse(dgSODetails.Rows[i].Cells[7].Value.ToString());


                h.SalesOrderDetails.Add(x);
            }

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message.ToString());
        }

    }

private SalesOrderHeader GetUIHeaderData()
        {
            SalesOrderHeader _soheader = new SalesOrderHeader();

            try
            {
                _soheader.CustName = cmbCustomerName.Text;
                _soheader.CustCity = textBoxCity.Text;
                _soheader.DocumentDate = dtDocDate.Value;
                _soheader.DeliveryDate = dtDeliveryDate.Value;

                _soheader.SalesPerson.Id = _SalesPersonShareMgr.LoadSalesPersonByName(cmbSalesPerson.Text).Id;
                _soheader.Customer = _CustShareMgr.LoadCustomerByName(cmbCustomerName.Text);


                _soheader.DocumentDate = dtDocDate.Value;
                _soheader.PostingDate = dtPostingDate.Value;
                _soheader.OrderDate = dtOrderDate.Value;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }

            return _soheader;
        }

private void buttonSave_Click(object sender, EventArgs e)
        {
            try
            {
                SalesOrderHeader objH = GetUIHeaderData(); 
                GetUIDetailData(objH);    

                _SOHeaderSharedMgr.SaveSOHeader(objH);

                MessageBox.Show("Sales Order Saved !");
            }
            catch (Exception ex)
            {    
                MessageBox.Show(ex.Message.ToString());
            }
        }

Код уровня данных

public void SaveSOHeader(SalesOrderHeader SO)
        {
            try
            {
                using (SODBContext db = new SODBContext())
                {
                    db.Entry(SO.SalesPerson).State = EntityState.Unchanged;
                    db.Entry(SO.Customer).State = EntityState.Unchanged;
                    db.Entry(SO.Customer.CustCity).State = EntityState.Unchanged;                  


                    db.SalesOrderHeaders.Add(SO);


                    foreach (SalesOrderDetail line in SO.SalesOrderDetails)
                     {
                        //line.SalesOrderHeader = SO;

                        db.Entry(line.Item).State = EntityState.Unchanged;
                        db.Entry(line.Item.UnitofMeasure).State = EntityState.Unchanged;
                        db.Entry(line.Item.ItemCategory).State = EntityState.Unchanged;                      

                        db.SalesOrderDetails.Add(line);
                    }



                    db.Entry(SO).State = EntityState.Added;


                    db.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

Вопрос заключается в следующем:

, когда я комментирую ниже код

db.Entry(line.Item).State = EntityState.Unchanged;
db.Entry(line.Item.UnitofMeasure).State = EntityState.Unchanged;
db.Entry(line.Item.ItemCategory).State = EntityState.Unchanged;

приведет к дублированию записи для элемента, категории элемента и единицы измерения. Раскомментируйте, что приведет к

Произошла ошибка при сохранении объектов, которые не предоставляют свойства внешнего ключа для их отношения. Свойство EntityEntries вернет значение NULL, поскольку один объект не может быть определен как источник исключения. Обработка исключений при сохранении может быть упрощена путем предоставления свойств внешнего ключа в типах объектов. Подробности см. В InnerException.

Это многоуровневое приложение

Мне нужен совет специалиста для решения этой проблемы.

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