前言

一直以来对EF和EF Core都是单独分开来写,从未以比较的形式来讲解,如果您既用过EF 6.x也用过用EF Core是否有了解过EF和EF Core在插入数据时和返回主键有何异同呢?本篇博客是坐在电脑旁本打算写写EF 6.x插入数据注意的问题,心想何不比较二者呢?我也是在探索中(边敲代码边写博客中),下面我们来看看。

EF 6.x和EF Core插入数据异同

            using (var ctx = new EfDbContext())
{
ctx.Database.Log = Console.WriteLine;
var customer = new Customer()
{
Email = "2752154844@qq.com",
Name = "Jeffcky",
Orders = new List<Order>()
{
new Order()
{
Code = "",
CreatedTime = DateTime.Now,
ModifiedTime = DateTime.Now,
Quantity = ,
Price =
}
}
};
}

上述Customer和Order为一对多关系,Order实体中有Customer实体的外键,上述我们同时给Customer和Order赋了值,所以当我们插入Customer的同时Order表中也插入了数据,此时Order的CustomerId是Customer的主键,我们根本不需要为Order中的CustomerId显式赋值,这一点毋庸置疑。我想说的是如果两个表没有很强的关联关系,怎么说呢,换言之两个表没有配置所谓的关系又或许我们没有配置关系,一个表中列需要用到另外一个表的主键,那么这种的情况下,我们会以怎样的方式插入数据呢?实践是检验真理的唯一标准,下面我们来试试。

    public class TestA
{
public int Id { get; set; }
public string Other { get; set; }
} public class TestB
{
public int Id { get; set; }
public int TestAId { get; set; }
public string Other { get; set; }
}
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<TestA>()
.ToTable("TestAs")
.HasKey(p => p.Id)
.Property(p => p.Other); modelBuilder.Entity<TestB>()
.ToTable("TestBs")
.HasKey(p => p.Id)
.Property(p => p.Other);
}

上述我们给出TestA和TestB,TestA和TestB没有任何关系,但是我们在插入TestB数据时需要得到Test的主键,那我们下面就进行如下数据添加。

            using (var ctx = new EfDbContext())
{
ctx.Database.Log = Console.WriteLine;
var testA = new TestA() { Other = "other" };
ctx.TestAs.Add(testA);
ctx.SaveChanges();
var testB = new TestB() { Other = "other", TestAId = testA.Id };
ctx.TestBs.Add(testB);
ctx.SaveChanges();
}

此时我们看到提交后数据最终能够保存到数据库中,反观上述提交代码,我们首先是提交了TestA保存到数据库后然后拿到TestA的主键,然后再是提交TestB并保存到数据库中。那我们有没有考虑是否直接一次性提交呢,注释TestA提交,如下:

            using (var ctx = new EfDbContext())
{
ctx.Database.Log = Console.WriteLine;
var testA = new TestA() { Other = "other" };
ctx.TestAs.Add(testA);
//ctx.SaveChanges();
var testB = new TestB() { Other = "other", TestAId = testA.Id };
ctx.TestBs.Add(testB);
ctx.SaveChanges();
}

WOW不行啊,下面我们来看看在EF Core中实现是不是可以,试试就知道了,别猜测。

            modelBuilder.Entity<TestA>(e =>
{
e.ToTable("TestAs");
e.HasKey(p => p.Id);
e.Property(p => p.Other);
}); modelBuilder.Entity<TestB>(e =>
{
e.ToTable("TestBs");
e.HasKey(p => p.Id);
e.Property(p => p.Other);
});
            using (var context = new EFCoreDbContext())
{
var testA = new TestA() { Other = "other" };
context.TestAs.Add(testA);
//ctx.SaveChanges();
var testB = new TestB() { Other = "other", TestAId = testA.Id };
context.TestBs.Add(testB);
context.SaveChanges();
}

如果分两次提交那么无论是在EF 6.x还是EF Core中都是一样没有任何不同(在EF Core中没有测试也不用测试)。如果是一次性提交,此时在EF 6.x中的TestB中的TestAId为插入的是0,而EF Core中的TestB中的TestAId为-2147482647即INT类型最小值,至少找到了不同所在。Jeff自问自答的模式要来了,是不是就这样结束了呢?上述我们对TestA和TestB两个实体未配置任何关系,我们经过测试证明一次性提交并未达到我们预期,要是我们依然在不配置关系的前提下给出导航属性然后一次性提交呢,如下:

    public class TestA
{
public int Id { get; set; }
public string Other { get; set; }
} public class TestB
{
public int Id { get; set; }
public int TestAId { get; set; }
public string Other { get; set; }
public TestA TestA { get; set; }
}

接下来我们在EF Core控制台再次运行上述代码看看,您思考下会不会将TestA中的主键添加进去呢。

如果您在EF 6.x中同样添加上述导航属性也是好使的,我就不测试了,那到此我们得出结论:若两个实体未显式配置任何关系但一个表需要得到另外一个表的主键,无论是在EF 6.x还是在EF Core中进行一次性提交不好使,只是在EF 6.x中一个表需要得到另外一个表的主键为0,而在EF Core中却是INT类型最小值,若我们显式配置了导航属性,那么无论是在EF 6.x还是EF Core中一次性提交可达到我们预期。

比较EF 6.x和EF Core插入数据返回主键

如果是主键为INT类型,默认情况无论是EF 6.x还是EF Core都将自动映射配置为自增长,要是我们显式配置了主键,那么对于EF 6.x和EF Core会有何不同呢?我们首先看看EF 6.x,如下(我们清除之前已提交数据):

            using (var ctx = new EfDbContext())
{
ctx.Database.Log = Console.WriteLine; var testA = new TestA() { Id = 1, Other = "other" };
ctx.TestAs.Add(testA);
ctx.SaveChanges();
}

从上述我们提交三次看出,压根不叼我们设置的值,那么我们看看生成的SQL语句是怎样的呢,如下图:

这下我们明白了此时通过scope_identity返回为当前会话和当前作用域中的TestA表生成的最新标识值。接下来我们来看看EF Core。

            using (var context = new EFCoreDbContext())
{
var testA = new TestA() { Id = , Other = "other" };
context.TestAs.Add(testA);
context.SaveChanges();
}

当我们进行第二次提交后将抛出异常,如下:

我们同样看看在EF Core中生成的SQL是怎样的。

原来如此没有返回当前会话自增长值,同时我们知道不能显式插入值,那就是关闭了IDENTITY_Insert。所以我们得出结论:在以INT作为主键且自增长时,在EF 6.x中能够显式给出值,而在EF Core中不能显式给定值即关闭了IDENTITY_INSERT不能显式插入主键值。

总结

本节我们详细叙述了EF 6.x和EF Core中插入数据和返回主键的不同之处,虽然作用不大,可以作为了解,最近比较累,可能会停更一小段时间,好好休息一下,书出版了会及时告知同行关注者。

EntityFramework 6.x和EntityFramework Core插入数据探讨的更多相关文章

  1. SQLAlchemy Core插入数据,有好几种方法呢

    看是一次插入一条还是多条, 看是数据表名是变量还是常量, 操作还是很灵活的, 主要看哪种顺手顺眼啦. #coding=utf-8 from datetime import datetime from ...

  2. [MSSQL] [EntityFramework(.Net Core)] 自增长id字段,无法插入数据

    IDENTITY_INSERT 为 OFF,无法插入数据, 类似的错误,解决记录: 网上查了下,都是 Code First 模式下的解决方案, 如:在 DBContext 的 OnModelCreat ...

  3. Webservice WCF WebApi 前端数据可视化 前端数据可视化 C# asp.net PhoneGap html5 C# Where 网站分布式开发简介 EntityFramework Core依赖注入上下文方式不同造成内存泄漏了解一下? SQL Server之深入理解STUFF 你必须知道的EntityFramework 6.x和EntityFramework Cor

    Webservice WCF WebApi   注明:改编加组合 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下, ...

  4. IdentityServer4 中文文档 -16- (快速入门)使用 EntityFramework Core 存储配置数据

    IdentityServer4 中文文档 -16- (快速入门)使用 EntityFramework Core 存储配置数据 原文:http://docs.identityserver.io/en/r ...

  5. EF批量插入数据(Z.EntityFramework.Extensions)

    EF用原生的插入数据方法DbSet.ADD()和 DbSet.AddRange()都很慢.所以要做大型的批量插入只能另选它法. 1.Nugget 2.代码 using EF6._0Test.EF; u ...

  6. 你必须知道的EntityFramework 6.x和EntityFramework Core变更追踪状态

    前言 只要有时间就会时不时去看最新EF Core的进展情况,同时也会去看下基础,把握好基础至关重要,本节我们对比看看如标题EF 6.x和EF Core的不同,希望对正在学习EF Core的同行能有所帮 ...

  7. EntityFramework 6.x和EntityFramework Core必须需要MultipleActiveResultSets?

    前言 本节我们来探讨到底需不需要在连接字符串上加上MultipleActiveResultSets = true ?,若您有更深层次的理解欢迎留下您的脚印. EntityFramework 6.x和E ...

  8. 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制

    你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...

  9. 我的EntityFramework(2):简单的数据查询

    原文:我的EntityFramework(2):简单的数据查询 在上一篇博文中,已经搭建了基本的框架,接下来就进行简单的数据查询,这里主要用了Linq 常见的数据集查询 var companyList ...

随机推荐

  1. Google的两种广告推广方式

    1搜索关键字广告推送:AdWords: 覆盖广泛:在全球最大的搜索和网络平台上进行推广. 定位精准:锁定目标客户群体,让潜在客户轻松找上门. 成本可控:仅当用户点击广告时,您才支付费用. 2.网站内容 ...

  2. 20_Android中apk安装器,通过WebView来load进一个页面,Android通知,程序退出自动杀死进程,通过输入包名的方式杀死进程

     场景:实现安装一个apk应用程序的过程.界面如下: 编写如下应用,应用结构如下: <RelativeLayout   编写activity_main.xml布局: <Relative ...

  3. 【算法导论】单源最短路径之Dijkstra算法

    Dijkstra算法解决了有向图上带正权值的单源最短路径问题,其运行时间要比Bellman-Ford算法低,但适用范围比Bellman-Ford算法窄. 迪杰斯特拉提出的按路径长度递增次序来产生源点到 ...

  4. 理解WebKit和Chromium: 网页渲染的基本过程

    转载请注明原文地址:http://blog.csdn.net/milado_nju ## 概述 前面介绍了一些渲染引擎的功能,包括网络,资源加载,DOM树,RenderObject树等等,但是,给人以 ...

  5. ViewPager适配器学习记录( pageAdapter和FragmentPagerAdapter/FragmentStatePagerAdapter))

    1.概述 ViewPager,顾名思义实现控件的滚动功能,是Support-v4的包中类,使用前要先导包.使用的时候跟listView有点相似,需要设置对应的适配器,通常有俩大类 [pageAdapt ...

  6. Leetcode_35_Search Insert Position

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43739647 Given a sorted array a ...

  7. linux下用gtk+写比赛赌博GUI小游戏

    游戏界面全部由gtk的GUI完成,没有使用openGL之类的高端货. 游戏玩法就是8位选手比赛跑步,你可以在赛前赌哪位选手会赢,如果输了cash会被扣除,反之cash会增加. 无聊写了3个选项:小数时 ...

  8. 用xml来编写动画

    我们可以使用代码来编写所有的动画功能,这也是最常用的一种做法.不过,过去的补间动画除了使用代码编写之外也是可以使用XML编写的,因此属性动画也提供了这一功能,即通过XML来完成和代码一样的属性动画功能 ...

  9. Android FrameWork浅识

    接收讯息及事件 储存共享数据 处理UI互动的事情 幕后服务(播放背景音乐) 在框架的手中,它的生命的周期完全由框架来控制,new也是由框架.它的逻辑调用则是自己实现,确保强龙的地位 框架反向来控制相应 ...

  10. Jenkins hash

    最早,Bob Jenkins提出了多个基于字符串通用Hash算法(搜Jenkins Hash就知道了),而Thomas Wang在Jenkins的基础上,针对固定整数输入做了相应的Hash算法.其64 ...