繁体   English   中英

如何使用 Entity Framework + OData POST 多个相关实体?

[英]How to POST multiple related entities with Entity Framework + OData?

发布多个相关实体并检查所需属性的正确方法是什么?

我有两个实体ProductPackage 一个Product可以有多个Packages 没有相关Product Package就不能存在。

当我发布具有多个Packages集合的新Product时, ModelState表示模型无效,因为Packages没有所需的productId外键集。 这会导致我的 API 返回BAD REQUEST状态。

我的理解是Entity Framework 支持这个 我希望ModelState检测到 Package productId FK 将自动设置,因此不会无效。

如果我删除检查ModelState有效性的代码块,实体框架会按预期运行,并且会创建ProductPackages

POST /api/v1/Products
BODY
{
   "name": "Coca-Cola",
   "packages": [
        {
            "count": 6,
            "quantity": 12,
            "quantityUnit": "oz"
        }
    ]
}

这是我的控制器功能:

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

这是我的模型:

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

我调查过的一些事情:

  1. 删除packageId上的[Required]属性并手动编辑数据库迁移以包含约束。 这会导致数据库稍后在堆栈中抛出错误。 我宁愿在进入数据库之前失败

  2. 编写我自己的验证属性。 鉴于 EF 文档声称支持这一点,这似乎没有必要

  3. 可能使用 OData 批量请求

我通常会创建一个非常具体的“模型”类(不是实体)来表示 HTTP Post(Put、Patch 等)的有效负载。 在这种情况下,您需要一组模型。 然后我有特定于这组模型的验证规则。 有些人称这些模型为 DTO、ViewModel 等。重要的是它们不是 EF 实体。

在验证它们的有效性之后,您必须将这些模型映射到适当的实体中,以便它们可以通过 EF 进行持久化。 这种映射是将实体与公开模型分离的不幸税收。 您可以手动执行此操作或使用automapper 之类的库。

这种策略有很多优点:

  • 您可以支持操作持久产品/包数据的多种变体,而不必用一组实体来适应每个变体。 这意味着您可以明智地为相同的持久化数据类型(实体)创建和公开具有不同验证规则的不同属性(模型)集。
  • 您可以保护自己免于过度发布 您不希望用户能够不受限制地设置所有属性的状态。
  • 您公开的端点(控制器操作)具有与您的实体分离的参数。 这意味着您可以自由更改实体,而不必更改表示它们的公开模型,反之亦然。 假设您可以完全放弃 EF,转而使用一些简洁的 NoSQL 持久性解决方案,而无需更改您的公开 API。

暂无
暂无

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

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