【问题标题】:How EF generate insertion SQL for entity class that has default 0?EF如何为默认为0的实体类生成插入SQL?
【发布时间】:2019-12-01 00:55:21
【问题描述】:

我是实体框架的新手,只是一个关于 EF 如何为默认为 0 的实体类生成插入 SQL 的问题。

这是数据模型类:

public class Product
{
    public long ProductID { get; set; }
    public string Name { get; set; }
}

Sql server 中的基础表 Products 在 ProductID 上有标识列。

假设一个控制器使用模型绑定来创建一个 Product 对象 p1,然后我们这样做:

context.Products.Add(p1)   //p1.ProductID = 0 for default
context.SaveChanges();

我的问题是:

  1. EF 是否需要向数据库发送查询以获取Products 表中的最新主键,然后加1 成为p1.ProductID?需要查询数据库以获取最新的现有主键,然后发送另一个插入 SQL 来插入记录,这不是非常低效吗?

  2. Dbset<Product>.add() 方法的真正含义是什么?我的意思是如果对象的 id 为 0,我们知道它在数据库中不存在(如果 id > 0 则我们知道我们正在修改现有记录),我们不能只是将新创建的 p1 添加到数据库中,为什么我们仍然需要追踪吗?

【问题讨论】:

  • 您可以使用 sql-profiler 来监控 EF 生成的 sql-queries
  • 要么您将主键定义为数据库中的 IDENTITY 列(首选选项) - 然后您的 SQL Server 将负责分发一个新的、唯一的键值 - 否则 必须提供一个值并确保它是唯一的。 EF 肯定会采用SELECT MAX(col)+1 方法......
  • @marc_s 是的 Products 表在 sql server 的 ProductID 上有 IDENTITY 列。但是 EF 怎么会知道这个事实呢?也许表中还有其他标识列,这就是为什么我认为 EF 必须做某事,例如向 Sql 服务器发送查询以“知道”哪些列是标识列?
  • 通过将[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 注释添加到您的键列......就这么简单......

标签: c# sql-server asp.net-mvc asp.net-core entity-framework-core


【解决方案1】:

1.) 不,您不需要获取最新对象的主键来确定下一个 Id。

2.) Primary Key starts from 1 not 0,在 EF 中,如果您使用下面解释的默认身份提供程序,EF 可以自动管理主键,因此无需将 ANY 数字设置为该变量。然后,context.Products.Add(p1) 将值添加到本地表(在 RAM 中),添加后 context.SaveChanges(); 将触发将本地值发送到 SQL 数据库。After SaveChanges you will see correct Id of value

有一个为表格生成自动 ID 的功能。

  • 首先,您应该选择哪个属性是具有[Key] 属性的主键。
  • 其次,你应该确定主键的类型是整数还是字符串(string has no auto Id Generator
  • 那么,如果是Integer,并且需要自动生成器,则应该使用[DatabaseGenerated(DatabaseGeneratedOption.Identity)]自动生成器。
  • 之后,你就不用担心ProductID EF 的值了。
public class Product
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long ProductID { get; set; }
    public string Name { get; set; }
}

不是:如果你想要字符串主键(或手动添加 Id)你应该使用[DatabaseGenerated(DatabaseGeneratedOption.None)]

more examples about EF(从导航器中选择 EF 版本)

【讨论】:

  • 感谢您的回答。对于 q2,Add() 的定义说它与跟踪有关,但是由于 p1 是创建的 py 模型绑定,这意味着它是新创建的记录,并且必须在任何地方插入到数据库中,所以为什么 p1 仍然需要跟踪?
  • 在使用 SaveChanges 之前,您的对象不在 db 中,而是在 localServer 上进行跟踪,它在使用 savechanges 之前就像在 db 中一样,因此您仍然可以引用该对象,但要确保成功阻止没有冲突进行保存更改。否则你会得到空引用错误,因为对象不会在 db
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-07
  • 2011-05-20
  • 2021-11-24
  • 1970-01-01
  • 2018-11-27
  • 2010-12-11
  • 2020-12-27
相关资源
最近更新 更多