Сохранение изменений из 1 записи с использованием Entity Framework обновляет 2 записи в базе данных

#c# #entity-framework

#c# #entity-framework

Вопрос:

У меня есть база данных, содержащая продажи клиентов. Я пытаюсь обновить 1 запись с помощью Entity Framework, но когда я проверяю свою базу данных, две записи были обновлены

Вызывается моя таблица Customers и содержит эти две записи:

 NameID    GenderID      ItemID          ShopID    Cost      
--------------------------------------------------------
587651    1              464             9         NULL 
587651    1              512             9         NULL 
 

Я хочу обновить первую запись, которую я пытаюсь сделать с помощью Entity Framework.

Это мой код:

 using (var context = new Customers())
{
    var _customers = (from all in context.Customers
                      where (all.NameID == 587651) amp;amp; 
                            (all.GenderID == 1) amp;amp;
                            (all.ItemID == 464) amp;amp; 
                            (all.ShopID == 9)
                      select all).First();
    _customers.Cost = 100;
    context.SaveChanges();
}
 

После сохранения изменений в моей базе данных я получаю следующее:

 NameID    GenderID      ItemID         ShopID     Cost      
--------------------------------------------------------
587651    1              464             9         100  
587651    1              512             9         100
 

Есть идеи, что происходит?

Комментарии:

1. Похоже, что nameid ошибочно принимается за первичный ключ

2. Вы уверены, что код, который вы показываете, является фактическим кодом, который создает проблему? Несмотря на то, что в коде есть проблема (с одним амперсандом в предикате where), вы выполняете First() , а затем изменяете один объект (является ли он правильным или нет, это только один), хотя вы показываете два обновленных объекта. Так что либо это не фактический проблемный код, и чего-то не хватает в показываемом вами примере кода, либо на уровне базы данных происходит что-то еще (триггеры или еще что-то)

3. @DanielWyatt эта база данных первая или сначала код? Если «nameid» используется в модели в качестве первичного ключа, но его нет в базе данных, то это МОЖЕТ объяснить это, но тогда вы должны показать, как настроена ваша модель

4. Да, это код, который я использую. Я выбираю первую запись и обновляю ее.

5. @DanielWyatt затем EF принимает NameID в качестве первичного ключа, однако это не определено как PK у поставщика базы данных… ваш перевод модели из базы данных неверен (этого не произошло бы, если EF создает базу данных или если вы ее перепроектировали). Генерируемое им предложение SQL будет примерно таким UPDATE customers SET Cost = 100 WHERE NameID = 587651 , которое будет соответствовать тому, что вы видите.

Ответ №1:

Хорошо, теперь я решил это, благодаря комментариям выше. Код, который определил мою таблицу, выглядел следующим образом:

 public partial class Customers
{
    [Key]
    [Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int NameJID { get; set; }

    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int GenderID { get; set; }

    public int? ItemID { get; set; }

    [Key]
    [Column(Order = 2)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ShopID { get; set; }

    public double? Cost { get; set; }
}
 

Как вы можете видеть, первичный ключ включает только NameID, GenderID и shopId. Обратите также внимание, что ItemId имеет значение null. Теперь я изменил код на этот:

 public partial class Customers
{
    [Key]
    [Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int NameJID { get; set; }

    [Key]
    [Column(Order = 1)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int GenderID { get; set; }

    [Key]
    [Column(Order = 2)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ItemID { get; set; }

    [Key]
    [Column(Order = 3)]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int ShopID { get; set; }

    public double? Cost { get; set; }
}
 

Комментарии:

1. действительно, все столбцы PK должны быть определены, поскольку они используются в качестве токенов параллелизма для всех операций CRUD (в частности, они используются для идентификации кортежей)