【问题标题】:Saving changes from 1 record using Entity Framework is updating 2 records in database使用实体框架保存 1 条记录的更改正在更新数据库中的 2 条记录
【发布时间】:2019-04-15 20:07:28
【问题描述】:

我有一个包含客户销售额的数据库。我正在尝试使用 Entity Framework 更新 1 条记录,但是当我检查我的数据库时,两条记录已被更新

我的表叫Customers,有这两条记录:

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

我想更新我尝试使用实体框架执行的第一条记录。

这是我的代码:

using (var context = new Customers())
{
    var _customers = (from all in context.Customers
                      where (all.NameID == 587651) && 
                            (all.GenderID == 1) &&
                            (all.ItemID == 464) && 
                            (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

知道发生了什么吗?

【问题讨论】:

  • 似乎nameid被误认为是主键
  • 您确定您显示的代码是导致问题的实际代码吗?即使代码存在问题(where 谓词上的单个&符号),您正在执行 First() 然后修改单个实体(无论那个实体是否正确,它只是一个)尽管您显示两个实体已更新。因此,要么这不是实际有问题的代码,并且您显示的示例代码中缺少某些内容,要么数据库级别发生了其他事情(触发器或诸如此类)
  • @DanielWyatt 这个数据库优先还是代码优先?如果“nameid”在模型上被用作主键但它不在数据库上,那么这可以解释它,但是你必须展示你的模型是如何配置的
  • 是的,这是我正在使用的代码。我正在选择第一条记录并更新该记录。
  • @DanielWyatt 然后 EF 将 NameID 作为主键,但是这并未定义为数据库提供程序上的 PK...您从数据库中的模型转换是错误的(如果EF 正在构建数据库,或者如果您对其进行了逆向工程)。它生成的 SQL 语句类似于 UPDATE customers SET Cost = 100 WHERE NameID = 587651,与您所看到的相匹配。

标签: c# entity-framework


【解决方案1】:

好的,多亏了上面的 cmets,我现在已经解决了这个问题。定义我的表的代码如下所示:

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 是如何为空的。我现在已将代码更改为:

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; }
}

【讨论】:

  • 确实,所有 PK 列都必须定义,因为它们被用作所有 CRUD 操作的并发标记(特别是它们用于标识元组)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
相关资源
最近更新 更多