Код элемента Entity Framework Первый метод AddOrUpdate insert Дублирующие значения

У меня есть простой объект:

public class Hall { [Key] public int Id {get; set;} public string Name [get; set;} } 

Затем в методе Seed я использую AddOrUpdate для заполнения таблицы:

 var hall1 = new Hall { Name = "French" }; var hall2 = new Hall { Name = "German" }; var hall3 = new Hall { Name = "Japanese" }; context.Halls.AddOrUpdate( h => h.Name, hall1, hall2, hall3 ); 

Затем я запускаю консоль управления пакетами:

 Add-Migration Current Update-Database 

Все в порядке: у меня три строки в таблице «Зал». Но если я снова заработаю в базе Update-Database консоли управления пакетами, у меня уже есть пять строк:

 Id Name 1 French 2 Japaneese 3 German 4 French 5 Japanese 

Зачем? Я думаю, что это должно быть три строки снова, а не пять. Я попытался использовать свойство Id вместо Name но это не имеет значения.

ОБНОВИТЬ:

Этот код дает тот же результат:

 var hall1 = new Hall { Id = 1, Name = "French" }; var hall2 = new Hall { Id = 2, Name = "German" }; var hall3 = new Hall { Id = 3, Name = "Japanese" }; context.Halls.AddOrUpdate( h => h.Id, hall1); context.Halls.AddOrUpdate( h => h.Id, hall2); context.Halls.AddOrUpdate( h => h.Id, hall3); 

Также у меня есть последняя EntityFramework, установленная через nuget.

Хорошо, я ударил свое лицо с клавиатуры в течение часа с этим. Если поле Id вашего поля является полем Identity, то оно не будет работать, поэтому используйте для выражения expressionExpression. Я использовал свойство Name, а также удалил поле Id из new Hall {...} инициализатора new Hall {...} .

Эта настройка для кода OPs работала для меня, поэтому я надеюсь, что это поможет кому-то:

 protected override void Seed(HallContext context) { context.Halls.AddOrUpdate( h => h.Name, // Use Name (or some other unique field) instead of Id new Hall { Name = "Hall 1" }, new Hall { Name = "Hall 2" }); context.SaveChanges(); } 

Этот код работает:

 public Configuration() { AutomaticMigrationsEnabled = true; } protected override void Seed(HallContext context) { context.Halls.AddOrUpdate( h => h.Id, new Hall { Id = 1, Name = "Hall 1" }, new Hall { Id = 2, Name = "Hall 2" }); context.SaveChanges(); } 

Я знаю, что это старый вопрос, но правильный ответ заключается в том, что если вы устанавливаете id # самостоятельно, и вы хотите использовать AddOrUpdate, тогда вам нужно сказать EF / SQL, что вы не хотите, чтобы он генерировал ID #.

 modelBuilder.Entity().Property(p => p.Id) .HasDatabaseGeneratedOption(System.ComponentModel .DataAnnotations.Schema.DatabaseGeneratedOption.None); 

Нижняя сторона этого заключается в том, что когда вы вставляете новый элемент, вам нужно установить его Id, поэтому, если это выполняется динамически во время выполнения (вместо данных семени), вам нужно будет вычислить следующий Id. Context.MyClasses.Max(c=>c.Id) + 1 работает хорошо.

Это также может быть вызвано, если вы неправильно установили состояние Entity. Я продолжал получать следующую ошибку при запуске базы данных обновлений … «Последовательность содержит несколько элементов соответствия».

Например, у меня были созданы повторяющиеся строки в каждой команде update-database (что, конечно, не должно происходить при посеве данных), а затем следующая команда базы данных обновлений не будет работать вообще, поскольку она обнаружила более одного совпадения (следовательно, ошибка последовательности, говорящая, что у меня есть несколько совпадающих строк). Это потому, что я переопределил SaveChanges в моем контекстном файле с вызовом метода ApplyStateChanges …

 public override int SaveChanges() { this.ApplyStateChanges(); return base.SaveChanges(); } 

Я использовал ApplyStateChanges, чтобы гарантировать, что при добавлении графов объектов Entity Framework четко определяет, находится ли объект в добавленном или измененном состоянии. Полное объяснение того, как я использую ApplyStateChanges, можно найти здесь .

И это отлично работает (но остерегается !!) … если вы также засеваете базу данных с помощью миграции CodeFirst, то указанный выше метод вызовет хаос для вызова AddOrUpdate () в методе Seed. Поэтому прежде чем что-либо еще, просто проверьте файл DBContext и убедитесь, что вы не переопределяете SaveChanges выше, или вы получите второй экземпляр дубликатов данных, выполняющих команду update-database, а затем не будете работать вообще в третий раз, поскольку для каждого совпадающего элемента имеется более одной строки.

Когда дело доходит до этого, вам не нужно настраивать Id в AddOrUpdate () …, который побеждает цели простого и начального посева базы данных. Он отлично работает:

 context.Students.AddOrUpdate( p => p.StudentName, new Student { StudentName = "Bill Peters" }, new Student { StudentName = "Jandra Nancy" }, new Student { StudentName = "Rowan Miller" }, new Student { StudentName = "James O'Dalley" }, 

просто AS LONG, поскольку я не переопределяю метод SaveChanges в своем контекстном файле с вызовом ApplyStateChanges. Надеюсь это поможет.

Это сработало для меня

  1. Удалите все строки в таблице.
  2. Сбросьте инкрементный идентификатор 0. DBCC CHECKIDENT (yourtablename, RESEED, 0) (Первичные ключи, указанные в Seed() должны совпадать с таковыми в таблице базы данных, чтобы они не дублировались.)
  3. Укажите первичные ключи в методе «семя».
  4. Запустите метод Seed() несколько раз, и вы проверяете, дублируются ли они.

Я обнаружил, что AddOrUpdate отлично работает с полями, которые не являются идентификаторами. Если это работает для вас: context.Halls.AddOrUpdate(h => h.Name, hall1, hall2, hall3)

Вы можете использовать имена Hall, такие как «French_test_abc_100», «German_test_abc_100» и т. Д.

Это останавливает жестко закодированные тестовые данные, когда вы тестируете свое приложение.

Если id объекта (hall) равен 0, это вставка. Я думаю, вам нужно дважды проверить поле id объектов вашего зала

Является ли поле ID поле «Идентификация»? Я столкнулся с этой проблемой. Когда я удалил статус Identity из моего поля ID и установил идентификаторы, входящие в базу данных, это решило проблему.

Это сработало для меня, поскольку они были справочными таблицами и, во всяком случае, не должны были областями идентификации.

Я думаю, что, скорее всего, вам нужно отменить существующие миграции баз данных (т. Е. Начать свою базу данных с нуля) с помощью чего-то вроде «Update-Database TargetMigration: 0», а затем «Update-Database».

Как бы то ни было, вы не отбрасываете существующую таблицу или значения, вы просто добавляете / обновляете эти значения. Это должно произойти, чтобы получить желаемый результат.

Вот хорошая ссылка для миграции EF: http://elegantcode.com/2012/04/12/entity-framework-migrations-tips/

Я использовал поле ID как Identity / Key и добавлял атрибуты, чтобы не назначать идентификаторы сервером. Это решило проблему для меня.

 public class Hall { [Key] [Required] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id {get; set;} public string Name [get; set;} } 

Только для ответа Ciaren, приведенный ниже код сброса контекста в ModelCreating, помог мне решить подобные проблемы. Убедитесь, что вы изменили «ApplicationContext» на свое имя DbContext.

 public class ApplicationContext : DbContext, IDbContext { public ApplicationContext() : base("ApplicationContext") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove(); Database.SetInitializer(null); base.OnModelCreating(modelBuilder); } } 

Вы могли бы также сделать это:

  context.Halls.AddOrUpdate(new Hall[]{hall1,hall2, hall3}); 

Я узнал, что для этого, работа над личностью, должна быть равна 0, когда семя сначала запускается. Вы можете сбросить его, используя:

 DBCC CHECKIDENT (tableName, RESEED, 0) 
  • Не удалось выполнить проверку для одного или нескольких объектов. Дополнительную информацию см. В разделе «Свойство EntityValidationErrors».
  • Entity Framework Code First Fluent Api: добавление индексов в столбцы
  • Использование Entity Framework с частной компактной установкой SQL Compact
  • Entity Framework 4 - AddObject vs Attach
  • Преобразование Entity Framework / Linq EXpression из строки в int
  • Entity Framework / Linq to SQL: Skip & Take
  • Тайм-ауты структуры организации
  • Ошибка API-интерфейса Asp.Net: тип «ObjectContent`1» не смог сериализовать тело ответа для типа контента «application / xml»; кодировка = UTF-8'
  • Почему структура Entity Framework не может видеть информацию о столбце хранимой процедуры?
  • Entity Framework - добавить свойство навигации вручную
  • Entity Framework 4 Удалить объект из коллекции объектов
  • Давайте будем гением компьютера.