Сначала код EF - не удалось обновить строку базы данных - PullRequest
3 голосов
/ 04 ноября 2010

Пробовал какой-то код с помощью метода EF "code first" и столкнулся со странной проблемой.

Мой текстовый текст:

    public class BookmarkerDataContext : DbContext
    {
        public DbSet<User> Users { get; set; }
        protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<User>().HasKey(u => u.UserId);
            base.OnModelCreating(modelBuilder);
        }
     }

Где пользовательский объект:

   public class User
    {
        public long UserId { get; set; }
        public ICollection<Tag> Tags { get; set; }
    }

В своем коде я делаю что-то довольно простое:

public void UpdateUserTags(User user,ICollection<Tag> taglist)
    {
        user.Tags = new List<Tag>(user.Tags.Union(taglist));
        datacontext.Users.Add(user);
        datacontext.SaveChanges();
    }

Объект пользователя, который я передаю этой функции, является результатом чего-то вроде:

datacontext.Users.SingleOrDefault(u => u.UserId==id)

Каждый раз, когда я вызываю функцию UpdateUserTags, создается впечатление, что вместо обновления она создает новую строку в таблице User. Я что-то здесь не так делаю?

Ответы [ 4 ]

4 голосов
/ 04 ноября 2010

@ Дональд прав, вам нужно Attach к ObjectContext при создании обновлений.

Однако это только в том случае, если ваша сущность отсоединена.

Если звучит так, как будто вы ужеизвлек одну единицу из графика:

var user = datacontext.Users.SingleOrDefault(u => u.UserId==id);

Это означает, что вам не нужно присоединять или получать его снова.Просто сделайте это:

var user = datacontext.Users.SingleOrDefault(u => u.UserId==id);
user.Tags = new List<Tag>(user.Tags.Union(taglist));
context.SaveChanges();

Однако я бы не рекомендовал заменить всю метку коллекцию, добавить метки:

user.Tags.Add(someTag);

НТН

3 голосов
/ 04 ноября 2010

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

public void UpdateUserTags(User user,ICollection<Tag> taglist)
{
    datacontext.Attach(user);
    user.Tags = new List<Tag>(user.Tags.Union(taglist));
    datacontext.SaveChanges();
}

Как только он присоединен, тогда контекст становится осведомленным об объекте.После сохранения изменений они должны быть сохранены в базе данных.

0 голосов
/ 04 ноября 2010

Это не имеет никакого отношения к вашей конкретной проблеме, но для ленивой загрузки вы хотите, чтобы теги были помечены как виртуальные

public virtual ICollection<Tag> Tags { get; set; }

Кроме того, похоже, что вы пытаетесь добавить новые теги дляпользователь (или обновите его теги), если это так, то вы захотите использовать Attach, как предложил Дональд

0 голосов
/ 04 ноября 2010

Не будет этой строки

datacontext.Users.Add (user);

Всегда отмечать запись пользователя как нуждающуюся в ДОБАВЛЕНИИ в таблицу пользователей.

Я думаю, что вы должны ОТКЛЮЧИТЬ пользователя из старого контекста и ПОДКЛЮЧИТЬ его к новому, чтобы правильно обновить запись.но я не EF Wonk, так мммм

...