【问题标题】:.NET API : Problem with posting object from postman.NET API:从邮递员发布对象的问题
【发布时间】:2020-02-24 18:05:43
【问题描述】:

我有一个名为 Classroom 的类,类似于:

    public class Classroom
    {
        [Key]
        public int ClassroomId { get; set; }

        public string ClassroomTitle { get; set; }

        public string AccessCode { get; set; }

        public string ColorPicker { get; set; }

        public LevelGroup LevelGroup { get; set; }
    }

LevelGroup 类类似于:

public class LevelGroup
    {
        public int MLevelId { get; set; }

        public int MGroupId { get; set; }

        public Level Level { get; set; }

        public Group Group { get; set; }
    }

在我的 API 中,我试图检索 Classroom 类型的数据,例如:

 [HttpPost("AddClassroom")]
 public async Task<JsonResult> AddClassroom([FromBody] Classroom classroom)
 {
        if (!ModelState.IsValid)
        {
            return Json(new ApiMessage
            {
                HasError = true,
                Message = "InvalidModel",
            });
        }

        try
        {
            _context.Add(classroom);
            await _context.SaveChangesAsync();

            return Json(new ApiMessage
            {
                HasError = false,
                Message = "Success"
            });
        }
        catch (Exception e)
        {
            return Json(new ApiMessage
            {
                HasError = true,
                Message = e.Message
            });
        }
 }

通过 POSTMAN,我尝试在某个 url 和 BODY 中访问 API,我已经传递了这个对象:

{
    "classroomTitle": "SWE",
    "accessCode": "6s1x4d1",
    "colorPicker": "blue",
    "levelGroup": {
        "mLevelId": 1,
        "mGroupId": 2
    }
}

但是,这不起作用。它说:

An exception occurred in the database while saving changes for context type 'mirror_api.Models.ApplicationDbContext'.
      Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
       ---> Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 19: 'UNIQUE constraint failed: LevelGroups.MGroupId, LevelGroups.MLevelId'.

如何解决这个问题?

【问题讨论】:

  • 错误很明显,LevelGroups.MGroupId, LevelGroups.MLevelId 列具有唯一约束,这意味着它们只能包含唯一且不存在的值。替换行、禁用唯一约束或启用列的自动增量。
  • 很可能您已经将此类实体添加到数据库中。您应该更改请求中新值所独有的属性,或者只是将您的方法重新设计为stackoverflow.com/questions/5557829/…
  • @nullptr.t 好吧,我明白你的意思了。但问题是,我不想在 LevelGroups 表中插入新行。我只想在课堂表中添加一个新行。而在课堂上,我只想弄清楚它属于哪个LevelGroup。另外需要注意的是,LevelGroup 类定义了另外两个类 Level 和 Group 的多对多关系。
  • @EugenePodskal 我猜它没有

标签: c# asp.net-core entity-framework-core


【解决方案1】:

根据您的 cmets,我了解您想要保存传递​​的对象,但您不想保存它的内部属性,因为它违反了一些数据库约束。

我会尝试在保存之前将这些属性从 EF 跟踪中分离出来,这样它就不会将 classroom.LevelGroup 标记为 Added。您可以查看this 示例。您还可以通过为添加到 EF 上下文 (docs) 的每个单独属性设置适当的状态来控制 EF 跟踪哪些对象的更改。

您还想阅读this,它几乎描述了您所寻求的内容:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };

using (var context = new BloggingContext())
{
    context.Blogs.Attach(existingBlog);
    context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some more work...  

    context.SaveChanges();
}

但不是附加对象,而是要添加它,然后将其属性之一设置为 EntityState.Detached 以完全忽略它(或 EntityState.Unchanged 继续跟踪它,但告诉 EF 此处没有可保存的内容) .更像这样的东西:

...
_context.Add(classroom);
_context.Entry(classroom.LevelGroup).State = EntityState.Detached;
await _context.SaveChangesAsync();
...

当您add 对象时,EF“开始跟踪给定实体和任何其他可访问的实体”,并且您可以“使用 State 仅设置单个实体的状态”,如图所示。

【讨论】:

    猜你喜欢
    • 2022-11-30
    • 2018-07-12
    • 2017-08-17
    • 1970-01-01
    • 2021-10-10
    • 2021-08-25
    • 2020-07-09
    • 2015-09-29
    • 1970-01-01
    相关资源
    最近更新 更多