EF Core中,通过实体类向SQL Server数据库表中插入数据后,实体对象是如何得到数据库表中的默认值的
我们使用EF Core的实体类向SQL Server数据库表中插入数据后,如果数据库表中有自增列或默认值列,那么EF Core的实体对象也会返回插入到数据库表中的默认值。
下面我们通过例子来展示,EF Core是怎么获取数据库的默认值的。首先我们建立一个.NET Core控制台项目,然后引入EF Core所需的NuGet包。
获取自增列值
我们在SQL Server数据库中建立一个表Person,该表有一个自增列ID为主键:
CREATE TABLE [dbo].[Person](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
[Age] [int] NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
然后我们使用EF Core的DB First将该表映射为实体类Person,如下所示:
public partial class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int? Age { get; set; }
}
实体类Person生成的Fluent API代码如下所示:
modelBuilder.Entity<Person>(entity =>
{
entity.Property(e => e.Id).HasColumnName("ID"); entity.Property(e => e.Name).HasMaxLength();
});
然后我们在Program类的Main方法中,通过实体类Person向数据库Person表中插入一行数据:
class Program
{
static void Main(string[] args)
{
using (var dbContext = new DemoDBContext())
{
Person person = new Person()
{
Name = "Tom",
Age =
}; dbContext.Person.Add(person);
dbContext.SaveChanges(); Console.WriteLine(person.Id);//输出:1
} Console.WriteLine("Press any key to end...");
Console.ReadKey();
}
}
我们在dbContext.SaveChanges()这行代码执行后,通过EF Core的后台日志可以查看到生成的SQL语句如下:
=============================== EF Core log started ===============================
Executed DbCommand (95ms) [Parameters=[@p0='?' (DbType = Int32), @p1='?' (Size = 50)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
INSERT INTO [Person] ([Age], [Name])
VALUES (@p0, @p1);
SELECT [ID]
FROM [Person]
WHERE @@ROWCOUNT = 1 AND [ID] = scope_identity();
=============================== EF Core log finished ===============================
可以看到EF Core最后使用了scope_identity()函数,来返回了刚刚插入的自增列ID的值。
获取默认值列
我们在SQL Server数据库中再建立一个表Book,该表有一个默认值列BookCode为主键,其默认值为函数newid():
CREATE TABLE [dbo].[Book](
[BookCode] [nvarchar](50) NOT NULL,
[BookName] [nvarchar](50) NULL,
[BookDescription] [nvarchar](50) NULL,
CONSTRAINT [PK_Book] PRIMARY KEY CLUSTERED
(
[BookCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO ALTER TABLE [dbo].[Book] ADD CONSTRAINT [DF_Book_BookCode] DEFAULT (newid()) FOR [BookCode]
GO
然后我们使用EF Core的DB First将该表映射为实体类Book,如下所示:
public partial class Book
{
public string BookCode { get; set; }
public string BookName { get; set; }
public string BookDescription { get; set; }
}
实体类Book生成的Fluent API代码如下所示:
modelBuilder.Entity<Book>(entity =>
{
entity.HasKey(e => e.BookCode); entity.Property(e => e.BookCode)
.HasMaxLength()
.HasDefaultValueSql("(newid())"); entity.Property(e => e.BookDescription).HasMaxLength(); entity.Property(e => e.BookName).HasMaxLength();
});
然后我们在Program类的Main方法中,通过实体类Book向数据库Book表中插入一行数据:
class Program
{
static void Main(string[] args)
{
using (var dbContext = new DemoDBContext())
{
Book book = new Book()
{
BookDescription = "English book",
BookName = "English"
}; dbContext.Add(book);
dbContext.SaveChanges(); Console.WriteLine(book.BookCode);//输出:B5AD3E33-3730-4545-8D45-9BD6DFCD5063
} Console.WriteLine("Press any key to end...");
Console.ReadKey();
}
}
我们在dbContext.SaveChanges()这行代码执行后,通过EF Core的后台日志可以查看到生成的SQL语句如下:
=============================== EF Core log started ===============================
Executed DbCommand (116ms) [Parameters=[@p0='?' (Size = 50), @p1='?' (Size = 50)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DECLARE @inserted0 TABLE ([BookCode] nvarchar(50), [_Position] [int]);
MERGE [Book] USING (
VALUES (@p0, @p1, 0)) AS i ([BookDescription], [BookName], _Position) ON 1=0
WHEN NOT MATCHED THEN
INSERT ([BookDescription], [BookName])
VALUES (i.[BookDescription], i.[BookName])
OUTPUT INSERTED.[BookCode], i._Position
INTO @inserted0; SELECT [t].[BookCode] FROM [Book] t
INNER JOIN @inserted0 i ON ([t].[BookCode] = [i].[BookCode])
ORDER BY [i].[_Position];
=============================== EF Core log finished ===============================
我们发现EF Core实际上是用SQL Server的Merge语句往数据库Book表中插入了数据,并且使用了Merge语句的OUTPUT关键字,来返回Book表中列BookCode插入的默认值。
我们可以自己写个Merge语句来实验下获取Book表中列BookCode插入的默认值:
DECLARE @R TABLE (BookCode NVARCHAR(50)) MERGE INTO [dbo].[Book]
USING (SELECT 1 AS [Number]) AS S ON 1=0
WHEN NOT MATCHED
THEN INSERT([BookName],[BookDescription]) VALUES(N'Chinese',N'Chinese Book')
OUTPUT
INSERTED.BookCode
INTO @R; SELECT * FROM @R
输出结果:

Book表的数据:

EF Core中,通过实体类向SQL Server数据库表中插入数据后,实体对象是如何得到数据库表中的默认值的的更多相关文章
- net core天马行空系列-各大数据库快速批量插入数据方法汇总
1.前言 hi,大家好,我是三合.我是怎么想起写一篇关于数据库快速批量插入的博客的呢?事情起源于我们工作中的一个需求,简单来说,就是有一个定时任务,从数据库里获取大量数据,在应用层面经过处理后再把结果 ...
- Java代码实体类生成SQL语句(Java实体类转数据库)
有的时候把数据库删了,如果照着实体类重新创建数据库的话比较麻烦,可以使用这个工具,把代码复制到项目里面设置一下即可把Java代码中的实体类转换为SQL语句输出为一个文件,打开执行命令即可. 下载:ht ...
- ASP.NET Core使用NLog记录日志到Microsoft Sql Server
在之前的文章中介绍了如何在ASP.NET Core使用NLog,本文为您介绍在ASP.NET Core使用NLog记录到Microsoft Sql Server 1.我们需要添加依赖: NLog.We ...
- 理解性能的奥秘——应用程序中慢,SSMS中快(2)——SQL Server如何编译存储过程
本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(1)--简介 本文介绍SQL Server如何编译存储过程并使用计划缓存 ...
- Java中的Date Time 与SQL Server 2005里的Datetime 之间的交互
Preface Environment:Platform: Windows XPLanguage: Java 1.5IDE: MyEclipse 6.0.1Database: SQL Server 2 ...
- 也谈SQL Server 2008 处理隐式数据类型转换在运行计划中的增强 (续)
在上一篇文章也谈SQL Server 2008 处理隐式数据类型转换在运行计划中的增强中,我提到了隐式数据类型转换添加对于数据分布非常不平均的表.评估的数据行数与实际值有非常大出入的问题,进一步測试之 ...
- sql server 使用SqlBulkCopy批量插入数据库
sql server sqlbulkcopy 批量数据插入数据库使用的是System.Data.SqlClient中的 SqlBulkCopy批量数据插入数据库 sql server 使用SqlBul ...
- SQL Server 2000向SQL Server 2008 R2推送数据
[文章摘要]最近做的一个项目要获取存在于其他服务器的一些数据,为了安全起见,采用由其他“服务器”向我们服务器推送的方式实现.我们服务器使用的是SQL Server 2008 R2,其他“服务器”使用的 ...
- SQL Server自增长列插入指定值 -- SET IDENTITY_INSERT ON|OFF(转)
想要将值插入到自动编号(或者说是标识列,IDENTITY)中去,需要设定 SET IDENTITY_INSERT 示例: 1.首先建立一个有标识列的表:CREATE TABLE products (i ...
随机推荐
- 13.Odoo产品分析 (二) – 商业板块(6) –采购(3)
接上一篇 查看Odoo产品分析系列--目录 接上一篇Odoo产品分析 (二) – 商业板块(6) –采购(2) 7. 仓库 仓库是在安装采购管理模块时出现的菜单.用于管理工厂库存,包括已经在手的货物 ...
- 系统调用fork()在powerpc上的源码分析
总结一句话:系统调用的本质,通过sc指令触发异常,完成用户态到内核的转换. 展开一些:应用程序调用fork(),fork()是一个glibc函数,该函数的最底层调用sc指令,触发cpu异常,从而完成从 ...
- DOM对象和window对象
本文内容: DOM对象 Window 对象 首发日期:2018-05-11 DOM对象: DOM对象主要指代网页内的标签[包括整个网页] 比如:document代表整个 HTML 文档,用来访问页面中 ...
- Python 套接字socketserver网络编程
为什么使用socketserver 虽然Python内置的socket和threading模块能实现简单的多线程服务器,在非正式环境,随便用用还是可以的,但是如果要在生产环境中使用,那是万万不够的. ...
- JAVA多线程的问题以及处理(二)【转】
使用互斥解决多线程问题是一种简单有效的解决办法,但是由于该方法比较简单,所以只能解决一些基本的问题,对于复杂的问题就无法解决了. 解 决多线程问题的另外一种思路是同步.同步是另外一种解决问题的思路,结 ...
- springmvc复习笔记----springmvc姓名年龄例子:RequestParam 试水
继续 继上节http://www.cnblogs.com/tk55/p/6652394.html 重要部分颜色突出 结构 包 web.xml 乱码处理方面设置 <url-pattern>* ...
- C#-简介(一)
1.C#语言简介 C#计算机语言 是一门高级计算机语言 他的开发模式更接近人类和社会的思维模式,有助于提高开发效率 C#历史 1998年COOL这个项目是C#语言的前身,由微软 Anders Hejl ...
- sql语句中的join用法(可视化解释)
一.innerjoin innerjoin总结来说就是 ,如A知道通往B如何走:B知道通往C如何走:但是A不知道通往C如何走,但是A可以通过B获得去往C的通往方式.. 首先,假设有A,B两张表,结构及 ...
- 想起以前写的一个爬虫,然后就用C#WinForm写了一个下载小说的软件,比较简单
本软件本是练习.讨论爬虫技术所用.如果侵犯了您的利益请联系我,我会立即删除! 小工具安装包: 百度网盘链接:https://pan.baidu.com/s/1m_OuEBOEE47kYaXq5fwpI ...
- replace函数使用方法
Replace函数的含义~ 用新字符串替换旧字符串,而且替换的位置和数量都是指定的. replace函数的语法格式 =Replace(old_text,start_num,num_chars,new_ ...