简体   繁体   English

实体框架6具有多重性1或0..1

[英]Entity Framework 6 has multiplicity 1 or 0..1

I am receiving the following error when trying to insert an object into a child collection after the model binder has created the model, children and grandchildren and then using context.SaveChanges(); 在模型绑定器创建模型,子代和孙代,然后使用context.SaveChanges();尝试将对象插入子集合中时,出现以下错误。

Multiplicity constraint violated. 违反多重性约束。 The role 'OrderDetail_OrderDetailPricelistProductOptions_Source' of the relationship 'PPLib.Models.OrderDetail_OrderDetailPricelistProductOptions' has multiplicity 1 or 0..1. 关系“ PPLib.Models.OrderDetail_OrderDetailPricelistProductOptions”的角色“ OrderDetail_OrderDetailPricelistProductOptions_Source”具有多重性1或0.1.1。

My models are as follows (removed properties for brevity); 我的模型如下(为简洁起见,删除了属性);

public class Order
{
    public int OrderId { get; set; }

    public virtual List<OrderDetail> OrderDetails { get; set; }
}

public class OrderDetail
{
    public int OrderDetailId { get; set; }

    public int OrderId { get; set; }

    public int ProductId { get; set; }
    public virtual Product Product { get; set; } //FK NAV

    public int? PricelistProductId { get; set; } // if a subscriber order ...has the ProductId from a PriceList.

    private decimal _Price = 0;
    public decimal Price  { get { return _Price; } set { _Price = value; } }

    private int _Quantity = 1;
    public int Quantity { get { return _Quantity; } set { _Quantity = value; } }

    public virtual List<OrderDetailPricelistProductOption> OrderDetailPricelistProductOptions { get; set; }

}

public class OrderDetailPricelistProductOption
{

    public int OrderDetailPricelistProductOptionId { get; set; }

    public int OrderDetailId { get; set; }

    public virtual List<OrderDetailPricelistProductOptionsDetail> OrderDetailPricelistProductOptionsDetails { get; set; }
}

public class OrderDetailPricelistProductOptionsDetail
{

    public int OrderDetailPricelistProductOptionsDetailId { get; set; }

    public int OrderDetailPricelistProductOptionId { get; set; }

    public string Name { get; set; }

}

To be clearer: 要更清楚:

If I submit a complete new Order, with a list of OrderDetails, its list of OrderDetailPricelistProductOptions and its list of OrderDetailPricelistProductOptionsDetails, the model binder does its job and I receive no error doing: 如果我提交一个完整的新Order,其中包含OrderDetails列表,OrderDetailPricelistProductOptions列表以及OrderDetailPricelistProductOptionsDetails列表,则模型绑定程序将执行其工作,并且在执行此操作时不会收到任何错误:

db.Orders.Add(order);
db.SaveChanges();

If I submit an Edit with and Existing Order and a NEW a list of OrderDetails, its list of OrderDetailPricelistProductOptions and its list of OrderDetailPricelistProductOptionsDetails, I get the Order from the DB context and then merge the OrderDetails from the view model, using: 如果提交带有现有订单的编辑和新建的OrderDetails列表,OrderDetailPricelistProductOptions列表及其OrderDetailPricelistProductOptionsDetails列表,则可以从数据库上下文中获取Order,然后使用以下方法从视图模型中合并OrderDetails:

order.OrderDetails.AddRange(pricelistProductVM.Order.OrderDetails);

and I receive no error doing: 而且我没有收到任何错误消息:

db.Entry(order).State = EntityState.Modified;
db.SaveChanges();

I have a particular situation, where I have to instantiate a new OrderDetail called autoFillOd, and inject its values from one of the existing OrderDetails assembled by the Model Binder. 我有一个特殊的情况,我必须实例化一个名为autoFillOd的新OrderDetail,并从Model Binder组装的现有OrderDetails中注入其值。 I change its Quantity value and then add it to the collection of OrderDetails in the ViewModel, like so: 我更改其数量值,然后将其添加到ViewModel中的OrderDetails集合中,如下所示:

pricelistProductVM.Order.OrderDetails.Add(autoFillOd);

When I do db.SaveChanges(), I receive the error. 当我执行db.SaveChanges()时,收到错误消息。

You'll notice that the error is on the child of the OrderDetails: OrderDetail_OrderDetailPricelistProductOptions_Source 您会注意到该错误是在OrderDetails的子级上:OrderDetail_OrderDetailPricelistProductOptions_Source

Why can I not add an OrderDetail dynamically into the collection of OrderDetails? 为什么不能将OrderDetail动态添加到OrderDetails的集合中? All the OrderDetails are new (to be inserted) so the values are the same between the copies, except for the Quantity property which should not be an issue. 所有OrderDetails是新的(将要插入),因此副本之间的值相同,但“数量”属性除外,这应该不是问题。

The controller action is as follows: 控制器动作如下:

[HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Add(pricelistProductVM pricelistProductVM)
    {
        OrderLogic ol = new OrderLogic();

        //Auth is running on execute

        int userId = WebSecurity.CurrentUserId;

        int websiteId = (int)Session["websiteId"];

        int? id = null; // mediaId

        int productId = pricelistProductVM.Product.ProductId;

        int? eventId = pricelistProductVM.eventId;

        string err = "";

        if (productId > 0)
        {
            //Set Pricelist
            Pricelist pricelist = ol.setPricelist(websiteId, id, eventId);

            if (pricelist.PricelistId != 0)
            {
                //get the pricelistproduct from the pricelist
                PricelistProduct pp = await (from ppx in db.PricelistProducts
                                             where ppx.ProductId == productId
                                             && ppx.PricelistId == pricelist.PricelistId
                                             && ppx.isAvailable == true
                                             && ppx.DiscontinuedDate == null
                                             && ppx.Product.isAvailable == true
                                             && ppx.Product.DiscontinuedDate == null
                                             select ppx).SingleOrDefaultAsync();
                if (pp != null)
                {
                    Order order = new Order();

                    //set some default values for the Order entity
                    if (pricelistProductVM.Order.OrderId == 0)
                    {
                        pricelistProductVM.Order.WebsiteId = websiteId;
                        pricelistProductVM.Order.UserId = userId;
                        pricelistProductVM.Order.EventId = eventId;
                        pricelistProductVM.Order.StartedDate = DateTime.UtcNow;
                        order = pricelistProductVM.Order;
                    }
                    else
                    {
                        order = await db.Orders.FindAsync(pricelistProductVM.Order.OrderId);
                    }


                    //set some default values for the OrderDetails entity
                    pricelistProductVM.Order.OrderDetails.First().InjectFrom(pp);
                    pricelistProductVM.Order.OrderDetails.First().IsPackage = false;


                    //determine if this product should be automatically added to any packages in the order
                    OrderDetail autoFillOd = ol.packageCheck(ref pp, ref pricelistProductVM, ref order, websiteId, db);
                    if (autoFillOd != null)
                    {
                        if (autoFillOd.Quantity > 0)
                        {
                            //This is where the OrderDetail that causes a problem is added
                            pricelistProductVM.Order.OrderDetails.Add(autoFillOd);
                        }
                    }

                    if (pricelistProductVM.Order.OrderId == 0)
                    {


                        db.Orders.Add(order);
                    }
                    else
                    {
                        order.OrderDetails.AddRange(pricelistProductVM.Order.OrderDetails);
                        db.Entry(order).State = EntityState.Modified;
                    }

                    db.SaveChanges();


                }
                else
                {
                    //return error
                    err = "The product was not found in the available pricelist. Please reload your browser and make sure you are signed-in.";
                }
            }

        }
        else
        {
            //return error
            err = "A productId was not passed so no product could not be found. Please reload your browser and make sure you are signed-in.";
        }


        if (err == "")
        {
            ViewBag.data = JsonConvert.SerializeObject(new { Success = 1, Msg = "The product was successfully added to your cart." });
        }
        else
        {
            ViewBag.data = JsonConvert.SerializeObject(new { Success = 0, Msg = err });
        }

        return View();
    }

I appreciate the help! 感谢您的帮助!

我认为OrderDetailPricelistProductOption.OrderDetailId不能单一->应该是列表,因为它可以出现在许多OrderDetails中...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM