odata v4客户端代码生成器:如何进行深度插入?

问题描述:

我拥有的是类似

var item1 = new Item { CODE = "ABC1", NAME = "A B C 1" };
var item2 = new Item { CODE = "ABC2", NAME = "A B C 2" };
var items = new DataServiceCollection<Item >{ item1, item2 };
var mt    = new MyType { CURRDATE = DateTime.Now.toString(), ITEMS = items };
_container.AddToMyType(mt);
var resp = _container.SaveChanges();
//...etc

是吗?在抱怨某事

"Unhandled Exception: System.InvalidOperationException: An item could not be added to the collection. When items in a DataServiceCollection are tracked by the DataServiceContext, new items cannot be added before items have been loaded into the collection."

据我所知,OData v4客户端不支持深度插入.

As far as I know, OData v4 client does not support deep insert.

一种方法是创建一个OData Action方法并序列化实体,然后再发送给OData Action方法并以字符串形式发送,然后在服务器端反序列化它.

One way to do this is to create an OData Action method and serialize the entity before sending to the OData Action method and send as a string, then deserialize it on the server side.

我在下面列出的另一个选项可以让您对父母/孩子进行"POST":

Another option I have listed below will let you do "POST" with parent / child:

/// <summary>
/// Deep insert parent and child.
/// </summary>
/// <param name="parentEntityPluralName"></param>
/// <param name="entity"></param>
public TEntity SaveWithChildren<TEntity>(string parentEntityPluralName, TEntity entity) where TEntity : BaseEntityType
{
    // need to serialize the entity so that we can send parent and child together
    string serializedEntity = Newtonsoft.Json.JsonConvert.SerializeObject(entity, new Newtonsoft.Json.JsonSerializerSettings() { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore });

    // create a handler for the httpclient
    using (System.Net.Http.HttpClientHandler httpHandler = new System.Net.Http.HttpClientHandler())
    {
        // create the httpclient and add the handler
        using (System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient(httpHandler))
        {
            // setup the headers
            httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Prefer", @"odata.include-annotations=""*""");
            httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "application/json;odata.metadata=minimal");

            // setup the content to send
            using (System.Net.Http.StringContent odataContent = new System.Net.Http.StringContent(serializedEntity))
            {
                // setup the content type to json
                odataContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");

                // post the data to the odata service
                using (System.Net.Http.HttpResponseMessage response = httpClient.PostAsync(this.BaseUri + parentEntityPluralName, odataContent).Result)
                {
                    // get back any errors or content
                    string content = response.Content.ReadAsStringAsync().Result;

                    // show error if service failed
                    if (response.IsSuccessStatusCode == false)
                    {
                        throw new Exception(content);
                    }

                    // try to convert the object back from the service call
                    return Newtonsoft.Json.JsonConvert.DeserializeObject<TEntity>(content);
                }
            }
        }
    }
}

将此方法放在属于您的代理"生成类的新类中.
然后调用您的Container类并调用SaveWithChildren方法.
这将调用父控制器的POST方法.
它仅调用父控制器的POST方法,您将不得不迭代服务器上的子代.

Place this method in a new class that is partial to your "proxy" generated class.
Then call your Container class and call the SaveWithChildren method.
This will call you parent controllers POST method.
It ONLY calls the parent controller POST method and you will have to iterate the children on the server.