首页 > 解决方案 > 实体框架标题,详细信息保存错误

问题描述

我是实体框架的新手,在分层应用程序中正确保存标题和详细记录的问题

这些是我的模型类:

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

}

表格代码

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;

将导致 Item , Item Category & , Unit of Measure 的记录重复 取消注释这将导致

保存不为其关系公开外键属性的实体时发生错误。EntityEntries 属性将返回 null,因为无法将单个实体标识为异常源。通过在实体类型中公开外键属性,可以更轻松地在保存时处理异常。有关详细信息,请参阅 InnerException。

这是一个分层的应用程序

我需要一些专家的建议来解决这个问题。

标签: c#.netwinformsentity-framework

解决方案


推荐阅读