0

考虑关注实体

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

根据上面的代码,供应商实体可以有零个或多个产品。在上述实体中,ID 由实体框架自动生成。

我正在使用 Odata V4 客户端代码生成器。

客户代码:

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

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

OdataContext.SaveChanges();

供应商控制器:

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

产品控制器:

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

当我保存更改时,我收到一条错误消息:

INSERT 语句与 FOREIGN KEY 约束冲突。

错误的原因是Product实体还没有SupplierId数据库生成的密钥。

那么如何在保存记录的同时添加SupplierIdProduct实体中呢?谁能帮我解决这个问题?

4

3 回答 3

0

好的,谢谢你的澄清。假设您使用的是 SQL Server,按照惯例,您的 Int Id 列将是标识列。一个产品可以有 0 个或 1 个供应商,所以从这个角度来看。

要将新产品添加到新供应商,您可以执行以下操作:

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();

要将现有供应商添加到产品:

// 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();
于 2016-02-23T16:14:43.963 回答
0

我认为 OData 客户端还不支持深度插入。所以另一种选择是对请求正文使用 WebClient 和 JSON 序列化程序,如下所示。父实体和子实体都将在单个 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());

供应商控制器中的发布操作 -

public async Task<IHttpActionResult> Post(Supplier supplier)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        db.Suppliers.Add(supplier);
        await db.SaveChangesAsync();
        return Created(supplier);
    }
于 2016-02-25T19:31:30.033 回答
0

使用 OData V4,您可以尝试深度插入方法。Deep Insert 允许在一个请求中创建相关实体树。http://docs.oasis-open.org/odata/odata/v4.0/os/part1-protocol/odata-v4.0-os-part1-protocol.html#_Toc372793718

于 2016-02-24T20:24:15.743 回答