.NET API : Problem with posting object from postman

2

I have a class named Classroom which is something like:

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

The LevelGroup class is something like:

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

        public int MGroupId { get; set; }

        public Level Level { get; set; }

        public Group Group { get; set; }
    }

In my API, I am trying to retrieve the data of type Classroom like:

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

From the POSTMAN, I tried to hit the API at some url and in the BODY, I've passed this object:

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

But, This is not working. It says:

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'.

How to solve this problem?

c#
asp.net-core
entity-framework-core
asked on Stack Overflow Feb 24, 2020 by Shunjid Rahman • edited Feb 24, 2020 by Shunjid Rahman

1 Answer

1

Based on Your comments I understand You want to save passed object but You do not want to save inner property of it as it violates some DB constraints.

What I would try is to detach those properties from EF tracking before saving so it won't mark classroom.LevelGroup as Added. You can see this example. You can also control which objects EF is tracking for changes by setting a proper state for each individual property that was added to the EF context (docs).

You also want to read this which nearly describes what You seek:

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

but instead of attaching the object, You want to add it and then set one of its properties as EntityState.Detached to ignore it completly (or EntityState.Unchanged to keep tracking it but tell EF that there is nothing to save here). Something more like this:

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

The moment You add the object, EF "gegins tracking the given entity, and any other reachable entities" and You can "Use State to set the state of only a single entity" as shown.

answered on Stack Overflow Feb 24, 2020 by Eatos • edited Feb 24, 2020 by Eatos

User contributions licensed under CC BY-SA 3.0