. NET API: проблема с отправкой объекта от почтальона - PullRequest
1 голос
/ 24 февраля 2020

У меня есть класс с именем 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 я пытаюсь получить данные типа Классная комната как:

 [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 я попытался запустить API по некоторому URL, а в BODY я передал этот объект :

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

Как решить эту проблему?

1 Ответ

1 голос
/ 24 февраля 2020

На основании ваших комментариев я понимаю, что вы хотите сохранить переданный объект, но вы не хотите сохранять его внутреннее свойство, поскольку оно нарушает некоторые ограничения БД.

Я бы попытался отсоединить эти свойства от EF отслеживание перед сохранением, поэтому classroom.LevelGroup не помечается как Added. Вы можете увидеть этот пример. Вы также можете контролировать, какие объекты EF отслеживает для изменений, устанавливая правильное состояние для каждого отдельного свойства, которое было добавлено в контекст 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();
...

В тот момент, когда вы добавляете объект, EF "отслеживает заданную сущность и любые другие достижимые сущности", и вы можете "использовать State для установки состояния только одной сущности ", как показано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...