首页 > 解决方案 > .NET API:从邮递员发布对象的问题

问题描述

我有一个名为 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'.

如何解决这个问题呢?

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

解决方案


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

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

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

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();
...

添加对象的那一刻,EF“跟踪给定实体和任何其他可访问实体”,并且您可以“使用状态设置仅单个实体的状态”,如图所示。


推荐阅读