EF Core не обновляет элементы внешнего ключа правильно - PullRequest
1 голос
/ 11 апреля 2020

Я пытаюсь обновить user и соответствующие им items, но у меня странное поведение. Более конкретно, user обновляется, но items добавляются в таблицу items, а предыдущие items, которые уже присутствовали в таблице, имеют UserId, равный null, и новые items имеют обновленные UserId.

Я пробовал разные вещи, такие как включение UserId и ItemId в мой вызов REST, но это приводит к System.InvalidOperationException для items. Тем не менее, добавление user и соответствующих им items к таблицам работает нормально.

public HttpStatusCode UpdateUsersAndItems(User user)
{
    if (ModelState.IsValid)
    {
        using (MyContext myContext = _myContext as MyContext)
        {
            User updateUser = myContext?.Users?.Include(i => i.Items).FirstOrDefault(u => u != null && u.UserName == user.UserName);

            if(updateUser != null)
            {
                updateUser.UserName = user.UserName;
                updateUser.Dob = user.Dob;
                updateUser.Location = user.Location;
                updateUser.Items = user.Items;

                myContext?.Users?.Update(updateUser);

                int changes = myContext.SaveChanges();

                if (changes > 0)
                {
                    return HttpStatusCode.Created;
                }
            }
        }
    }

    return HttpStatusCode.NotModified;
}

namespace TestWebApplication.Database
{
    public class User
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string Dob { get; set; }
        public string Location { get; set; }

        public ICollection<Items> Items { get; set; }
    }
}


namespace TestWebApplication.Database
{
    public class Items
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ItemId { get; set; }
        public string Item { get; set; }
        public string Category { get; set; }
        public string Type { get; set; }

        public int? UserId { get; set; }

        [ForeignKey("UserId")]
        public virtual User User { get; set; }
    }
}

Rest call

{
    "username": "xxx",
    "dob": "xxx",
    "location": "xxx",
    "items":[{
        "item": "xxx",
        "category": "xxx",
        "type": "xxx"
        },
        {
        "item": "xxx",
        "category": "xxx",
        "type": "xxx"
        },
        {
        "item": "xxx",
        "category": "xxx",
        "type": "xxx"
        }]
}

1 Ответ

1 голос
/ 11 апреля 2020

Вы должны go пройти через каждый элемент и изменить его свойства.

Как-то так.

       using (MyContext myContext = _myContext as MyContext)
        {
            User updateUser = myContext?.Users?.Include(i => i.Items).FirstOrDefault(u => u != null && u.Id == user.Id);

            if(updateUser != null)
            {
                updateUser.UserName = user.UserName;
                updateUser.Dob = user.Dob;
                updateUser.Location = user.Location;
                foreach( var userItem in user.Items )
                {
                   var updateItem = updateUser.Items.SingleOrDefault( i => i.Id == userItem.Id );
                   if( updateItem == null )
                   {
                     updateItem = new Items {
                       Type = userItem.Type,
                       Category = userItem.Category
                     };
                     updateUser.Items.Add(updateItem);
                   }
                   else
                   {
                     updateItem.Type = userItem.Type;
                     updateItem.Category = userItem.Category;
                   }
                }


                int changes = myContext.SaveChanges();

                if (changes > 0)
                {
                    return HttpStatusCode.Created;
                }
            }
        }

Я не вижу, как вы уникально идентифицируете свой предметы, но не открывайте свои первичные ключи для веб-интерфейса (веб)

...