简体   繁体   English

Asp.Net WebApi OData v4-保存实体以及相关实体

[英]Asp.Net WebApi OData v4 - Saving Entity along with related entities

Consider following Entities 考虑以下实体

public class Supplier
{
    public int Id { get; set; }
    public string Name { get; set; }

    public ICollection<Product> Products { get; set; }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Category { get; set; }  

    public int? SupplierId { get; set; }
    public virtual Supplier Supplier { get; set; }
}

As per the code above a Supplier entity can have zero or more products. 根据上面的代码,供应商实体可以拥有零个或多个产品。 In above entities the ID's are auto-generated by Entity Framework. 在上述实体中,ID由实体框架自动生成。

I'm using Odata V4 Client code generator. 我正在使用Odata V4客户端代码生成器。

Client Code: 客户代码:

Supplier s = new Supplier{...}
OdataContext.AddToSuppliers(s);

Product p = new Product{...}
p.SupplierId = s.Id;
OdataContext.AddToProduct (p);

OdataContext.SaveChanges();

Supplier Controller: 供应商控制器:

public async Task<IHttpActionResult> Post(Supplier supplier)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    db.Supplier.Add(supplier);
    await db.SaveChangesAsync();
    return Created(supplier);
}

Product Controller: 产品负责人:

public async Task<IHttpActionResult> Post(Product product)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    db.Products.Add(product);
    await db.SaveChangesAsync();
    return Created(product);
}

When I saving the changes I'm getting an error message: 保存更改时,出现错误消息:

The INSERT statement conflicted with the FOREIGN KEY constraint. INSERT语句与FOREIGN KEY约束冲突。

The reason for the error is the Product entity doesn't have the SupplierId yet as it Database generated key. 错误的原因是Product实体还没有SupplierId ,因为它是数据库生成的密钥。

So how can I add SupplierId to the Product entity while saving the record? 那么如何在保存记录的同时将SupplierId添加到Product实体? Can anyone help me to solve this issue? 谁能帮我解决这个问题?

OK, thanks for clarifying. 好的,谢谢您的澄清。 Assuming you are using SQL Server, your Int Id columns will be identity columns by convention. 假设您正在使用SQL Server,则按照惯例,您的Int Id列将是Identity列。 A Product can have 0 or 1 supplier so approach from that perspective. 一个产品可以有0个或1个供应商,因此从该角度考虑。

To add a new product to a new supplier you can do: 要将新产品添加到新供应商,您可以执行以下操作:

Supplier s = new Supplier
{
    Name = "mySupplier"
}

Product p = new Product
{
    Name = "myname",
    Price = 123.45,
    Category = "myCategory",
    Supplier = s
}

OdataContext.Products.Add(p);
OdataContext.SaveChanges();

To add an existing supplier to a product: 要将现有供应商添加到产品中:

// select a supplierId or search by name
var supplier = OdataContext.Suppliers.FirstOrDefault(s => s.Name == nameToFind);
if (supplier == null) // Handle no match

Product p = new Product
{
    Name = "myname",
    Price = 123.45,
    Category = "myCategory",
    SupplierId = supplier.Id
}

OdataContext.Products.Add(p);
OdataContext.SaveChanges();

With OData V4, You may try the deep insert approach. 使用OData V4,您可以尝试深度插入方法。 Deep Insert allows creating a tree of related entities in one request. 深度插入允许在一个请求中创建一棵相关实体的树。 http://docs.oasis-open.org/odata/odata/v4.0/os/part1-protocol/odata-v4.0-os-part1-protocol.html#_Toc372793718 http://docs.oasis-open.org/odata/odata/v4.0/os/part1-protocol/odata-v4.0-os-part1-protocol.html#_Toc372793718

I think OData Client won't support the deep insert yet. 我认为OData Client尚不支持深度插入。 So another option is to use WebClient and JSON serializer for request body, like below. 因此,另一个选择是将WebClient和JSON序列化程序用于请求正文,如下所示。 Both parent and child entities will be created in single http request and foreign key will get updated accordingly - 父实体和子实体都将在单个http请求中创建,并且外键将相应地更新-

var product = new ProductService.Models.Product()
        {
            Name = "My Car",
            Category = "Auto",
            Price = 4.85M
        };

        var supplier = new ProductService.Models.Supplier()
        {
            Name = "My Name"
        };

        //Add product to supplier
        supplier.Products.Add(product);

        WebClient client = new WebClient();
        client.BaseAddress = "http://example.com/OData";
        client.Headers.Add("Content-Type", "application/json");

        //Serialize supplier object
        var serializer = new JavaScriptSerializer();
        var serializedResult = serializer.Serialize(supplier);

        //Call the service
        var result = client.UploadString("http://example.com/OData/Suppliers", serializedResult.ToString());

Post Action in Suppliers Controller - 供应商控制器中的后期操作-

public async Task<IHttpActionResult> Post(Supplier supplier)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        db.Suppliers.Add(supplier);
        await db.SaveChangesAsync();
        return Created(supplier);
    }

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

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