UpdateRelatedObject方法仅在sourceProperty不是集合时才有效

时间:2014-11-27 10:15:28

标签: asp.net-web-api odata

当我尝试使用asp.net webapi OData更新对象树时出现以下错误:

"UpdateRelatedObject method only works when the sourceProperty is not collection." 

我的代码如下。当mehod" UpdateRelatedObject"叫做。你能告诉我我的代码有什么问题,以及如何使用asp.net webapi odata v4更新对象树(意思是对象包含子对象的集合)。

var container = new Container(new Uri("http://JohnAlbert.com/MyOdataTest/odata"));
            Product product = container.Products.Expand(p=> p.ProductItems).Expand(p=>p.ProductInvoices).Where(p => p.PId == Guid.Parse("28C508B8-F2DC-45C2-B401-7F94E79AB347")).FirstOrDefault();
            if (product != null)
            {
                product.Name = product.Name + "_Modified";

                var pitem1 =  product.ProductItems[0];
                product.ProductItems.Remove(pitem1);
                container.UpdateRelatedObject(product, "ProductItems", pitem1);


                var pitem2 = product.ProductItems[0];
                pitem2.Price = 999;
                container.UpdateRelatedObject(product, "ProductItems", pitem1);

                var pInv1 = product.ProductInvoices[0];
                product.ProductInvoices.Remove(pInv1);
                container.UpdateRelatedObject(product, "ProductInvoices", pInv1);

            }
            container.UpdateObject(product);

            container.SaveChanges(SaveChangesOptions.BatchWithSingleChangeset);

2 个答案:

答案 0 :(得分:0)

您实际想要删除实体的集合值导航属性中的某些项与其自身之间的关系。在这种情况下,DeleteLink()是正确的使用方法。在这种情况下,以下代码应该完成工作:

if (product != null)
        {
            var pitem1 =  product.ProductItems[0];
            var pitem2 = product.ProductItems[0];
            var pInv1 = product.ProductInvoices[0];

            container.DeleteLink(product, "ProductItems", pitem1);
            container.DeleteLink(product, "ProductItems", pitem2);
            container.DeleteLink(product, "ProductInvoices", pInv1);

            container.SaveChanges();
        }

您可能认为上述方式不像使用.Remove()直接从实体中删除导航项一样直观。对于此问题,使用DataServiceCollection<T>启用的实体跟踪可以提供帮助。您可以将此博客文章用作如何使用DataServiceCollection<T>http://blogs.msdn.com/b/odatateam/archive/2014/04/10/client-property-tracking-for-patch.aspx

的教程

答案 1 :(得分:0)

要删除包含的导航属性,可以使用DataServiceContext.DeleteObject。

要删除实体及其导航属性之间的关系,可以使用DataServiceContext.DeleteLink

要更新对象,可以使用DataServiceContext.UpdateObject。 因此,根据您的方案,您可以使用以下代码

        if (product != null)
        {
            product.Name = product.Name + "_Modified";
            dsc.UpdateObject(product);

            var pitem1 =  product.ProductItems[0];
            //This is to remove relationship
            container.DeleteLink(product, "ProductItems", pitem1);
            // This is to remove the object
            //container.DeleteObject(pitem1);


            var pitem2 = product.ProductItems[0];
            pitem2.Price = 999;
            container.UpdateObject(pitem2);

            var pInv1 = product.ProductInvoices[0];
            //This is to remove relationship
            container.DeleteLink(product, "ProductInvoices", pInv1);
            // This is to remove the object
            //container.DeleteObject(pInv1);

            container.SaveChanges(SaveChangesOptions.BatchWithSingleChangeset);

        }