C# Asp.Net WebApi OData v4-保存实体和相关实体

C# Asp.Net WebApi OData v4-保存实体和相关实体,c#,entity-framework,asp.net-web-api,odata,odata-v4,C#,Entity Framework,Asp.net Web Api,Odata,Odata V4,考虑以下实体 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;

考虑以下实体

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; }
}
供应商控制员:

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);
}
公共异步任务岗(供应商)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
db.Supplier.Add(供应商);
等待db.saveChangesSync();
已创建退货(供应商);
}
产品控制员:

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);
}
公共异步任务发布(产品)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
db.Products.Add(产品);
等待db.saveChangesSync();
已创建的退货(产品);
}
保存更改时,我收到一条错误消息:

INSERT语句与外键约束冲突

出现错误的原因是
产品
实体在数据库生成密钥时没有
供应商ID

那么,如何在保存记录时将
SupplierId
添加到
Product
实体?
有人能帮我解决这个问题吗?

好的,谢谢你的澄清。假设您使用的是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();

对于ODataV4,您可以尝试深度插入方法。深度插入允许在一个请求中创建相关实体的树

我认为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);
    }
公共异步任务岗(供应商)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
db.Suppliers.Add(供应商);
等待db.saveChangesSync();
已创建退货(供应商);
}

是的,我同意,这个问题是错的。现在我编辑了这个问题。在您的示例中,您正在这样做:
s.ProductId=p.ProductId
据我所知,仍然
p.ProductId
没有值,对吗?那么这个任务是如何工作的呢?它将从数据库序列中获取值,对吗?你能解释一下吗?我已经修改了代码并运行了解决方案,但还是遇到了同样的错误。>INSERT语句与外键约束“FK_dbo.Product_dbo.Supplier_SupplierId”冲突。冲突发生在数据库“DBContext”、表“dbo.Supplier”、列“Id”中。声明已终止。我调试并注意到供应商是在数据库中创建的,而不是在产品中创建的。这正是我所需要的。但我如何在DataService客户端或ODataV4客户端中实现这一点呢