[英]How to POST multiple related entities with Entity Framework + OData?
What is the proper way to POST multiple related entities and check required properties?发布多个相关实体并检查所需属性的正确方法是什么?
I have two entities Product
and Package
.我有两个实体
Product
和Package
。 A Product
can have many Packages
.一个
Product
可以有多个Packages
。 A Package
cannot exist without a related Product
.没有相关
Product
Package
就不能存在。
When I POST a new Product
with a collection of multiple Packages
, the ModelState
says the model is invalid because the Packages
do not have their required productId
foreign key set.当我发布具有多个
Packages
集合的新Product
时, ModelState
表示模型无效,因为Packages
没有所需的productId
外键集。 This causes my API to return a BAD REQUEST
status.这会导致我的 API 返回
BAD REQUEST
状态。
It's my understanding that Entity Framework supports this .我的理解是Entity Framework 支持这个。 I would expect the
ModelState
to detect that the Package productId
FK will be set automatically and thus wouldn't be invalid.我希望
ModelState
检测到 Package productId
FK 将自动设置,因此不会无效。
If I remove the block of code that checks the ModelState
validity Entity Framework behaves as expected and the Product
and Packages
are created.如果我删除检查
ModelState
有效性的代码块,实体框架会按预期运行,并且会创建Product
和Packages
。
POST /api/v1/Products
BODY
{
"name": "Coca-Cola",
"packages": [
{
"count": 6,
"quantity": 12,
"quantityUnit": "oz"
}
]
}
Here is my controller function:这是我的控制器功能:
[HttpPost]
[ODataRoute("")]
[EnableQuery]
public virtual async Task<IActionResult> PostEntity([FromBody] Product entityToCreate)
{
//Removing this block will cause the request to succeed
// but will also allow invalid requests to get to the database
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.Packages.Add(entityToCreate);
await _context.SaveChangesAsync();
return Created("DefaultApi", entityToCreate);
}
And here are my models:这是我的模型:
public class Product: ModelBase
{
[Required]
public string name { get; set; }
public List<Package> packages { get; set; }
}
public class Package: ModelBase
{
//some required props...
[Required]
[ForeignKey("product")]
public Guid? productId { get; set; }
public Product product { get; set; }
}
Some things I've investigated:我调查过的一些事情:
Dropping the [Required]
attribute on packageId
and manually editing the db migration to include the constraint.删除
packageId
上的[Required]
属性并手动编辑数据库迁移以包含约束。 This causes an error to be thrown later in the stack by the database.这会导致数据库稍后在堆栈中抛出错误。 I'd rather fail before getting to the database
我宁愿在进入数据库之前失败
Writing my own validation attributes.编写我自己的验证属性。 This seems unnecessary given that the EF documentation claims to support this
鉴于 EF 文档声称支持这一点,这似乎没有必要
Possibly using OData Batch Requests可能使用 OData 批量请求
I typically create a very specific "model" class (not an entity) to represent the payload of an HTTP Post (Put, Patch, etc.).我通常会创建一个非常具体的“模型”类(不是实体)来表示 HTTP Post(Put、Patch 等)的有效负载。 In this case you'd want a set of models.
在这种情况下,您需要一组模型。 Then I have validation rules specific this set of models.
然后我有特定于这组模型的验证规则。 Some call these models, DTOs, ViewModels, etc. The important thing is that they are not EF entities.
有些人称这些模型为 DTO、ViewModel 等。重要的是它们不是 EF 实体。
After verifying their validity, you will have to map these models into the appropriate entities so they can be persisted with EF.在验证它们的有效性之后,您必须将这些模型映射到适当的实体中,以便它们可以通过 EF 进行持久化。 This mapping is the unfortunate tax of decoupling your entities from your exposed models.
这种映射是将实体与公开模型分离的不幸税收。 You can do this manually or use a library like automapper .
您可以手动执行此操作或使用automapper 之类的库。
There are many advantages to this strategy:这种策略有很多优点:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.