Asp.Net WebApi OData v4 - 保存实体以及相关实体
本文关键字:实体 保存 Net WebApi OData v4 Asp | 更新日期: 2023-09-27 18:35:54
>考虑以下实体
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
,因为它是数据库生成的密钥。
那么如何在保存记录的同时向Product
实体添加SupplierId
呢?谁能帮我解决这个问题?
好的,谢谢你的澄清。假设您使用的是 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();
使用 OData V4,您可以尝试深度插入方法。深层插入允许在一个请求中创建相关实体的树。http://docs.oasis-open.org/odata/odata/v4.0/os/part1-protocol/odata-v4.0-os-part1-protocol.html#_Toc372793718
我认为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);
}