本文转自:http://blog.csdn.net/educast/article/details/8632806

与Entity Framework相伴的日子痛并快乐着。今天和大家分享一下一个快乐,两个痛苦。

先说快乐的吧。Entity Framework在将数据插入数据库时,如果主键字段是自增标识列,会将该自增值返回给实体对象对应的属性。

比如下面添加博客随笔至数据库的示例代码:

var blogPost = new BlogPost()
{
Author = "博客园",
Title = "程序员的网上家园"
};
using (BlogDbContext context = new BlogDbContext())
{
context.BlogPosts.Add(blogPost);
context.SaveChanges();
return blogPost.ID;
}

SaveChanges()之后,blogPost.ID的值就是数据库中对应自增标识列的值。

看一下Entity Framework生成的SQL语句:

exec sp_executesql N'insert [dbo].[blog_Content]([Title],[Author])
values (@0, @1)
select [ID]
from [dbo].[blog_Content]
where @@ROWCOUNT > 0 and [ID] = scope_identity()',
N'@0 nvarchar(128),@1 nvarchar(128),',@0=N'程序员的网上家园',@1=N'博客园'

EF通过scope_identity()获取自增列的值,而且我们没有对BlogPost的ID属性进行任何设置,是EF智能地判断出ID就是自增标识列。

在以前没有使用Entity Framework的时代,用的是存储过程,存储过程有一堆参数,实体对象的属性值要一一对应地赋值给这些参数,执行存储过程之后,还要通过ParameterDirection.Output的参数获取自增ID的值。

现在,只要把东西交给Entity Framework,并和她说,把它放到数据库中去。多省心!多快乐!

但是,自以为是的Entity Framework用这个特性给人快乐的同时,也给人带来了一点痛苦。她认为只要实体类中有ID属性,数据库对应的是一定是自增标识列,真是够自以为是的。当我们把博客随笔添加至数据库后,准备用这个自增ID将随笔内容添加至数据库(随笔内容存储在单独的数据库,通过ID字段与随笔进行关联,不是自增的),却出现错误提示:

Cannot insert the value NULL into column 'ID', 
table 'CNBlogsText.dbo.blog_PostBody'; column does not allow nulls.

看看EF生成的SQL语句:

exec sp_executesql N'insert [dbo].[CNBlogsText_blog_PostBody]([Text])
values (@0)
select [ID]
from [dbo].[CNBlogsText_blog_PostBody]
where @@ROWCOUNT > 0 and [ID] = scope_identity()',N'@0 nvarchar(128)',@0=N'帮助程序员用技术改变世界'

不是自增列,也来个scope_identity()。这么聪明的Entity Framework,也会干这样的傻事。

还好,EF定制灵活的特性可以让我们轻松化解这个痛苦,只要在BlogDbContext中添加下面的代码:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<PostBody>().Property(p => p.ID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}

也可以通过在实体类属性上加标记实现:

public class BlogPost
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }
}

第二个痛苦是众所周知的Entity Framework不支持枚举类型,虽然大家都知道,但还是想拿出晒晒,解解恨。

EF怎么对待枚举类型的呢?对于实体类中实实在在存在的枚举类型的属性,EF对它们视而不见,就当它不存在。

对于这个痛苦,目前无法化解(要等EF的下一版本),只能借助旁边左道减轻痛苦,请看“旁边左道”之“移花接木”。

实体类中的代码:

public class BlogPost
{
public BlogPostType PostType
{
get { return (BlogPostType)PostTypeEf; }
set { PostTypeEf = (int)value; }
}
public int PostTypeEf { get; set; }
}

EF不认枚举类型,但认int类型,所以增加个PostTypeEf,仅供EF专用,等EF的下一版本支持枚举类型时再去掉。

BlogDbContext也要

[转] Entity Framework添加记录时获取自增ID值的更多相关文章

  1. Entity Framework添加记录时获取自增ID值

    与Entity Framework相伴的日子痛并快乐着.今天和大家分享一下一个快乐,两个痛苦. 先说快乐的吧.Entity Framework在将数据插入数据库时,如果主键字段是自增标识列,会将该自增 ...

  2. mybatis添加记录时返回主键id

    参考:mybatis添加记录时返回主键id 场景 有些时候我们在添加记录成功后希望能直接获取到该记录的主键id值,而不需要再执行一次查询操作.在使用mybatis作为ORM组件时,可以很方便地达到这个 ...

  3. Entity Framework: 视图查询时重复返回第一行值, duplicate frst rows in resultset from a view

    http://blog.csdn.net/riverlau/article/details/7476449 1. 使用rownumber给view加上一个标示列 SELECT ROW_NUMBER() ...

  4. 使用mybatis注解@Options实现添加记录时返回主键值

    官网:http://www.mybatis.org/mybatis-3/index.html 在使用mybatis作为ORM框架时,我通常更喜欢使用注解而非xml配置文件的方式.业务场景:添加记录之后 ...

  5. ThinkPHP 3.2.3+ORACLE插入数据BUG修复及支持获取自增Id的上次记录

    TP+ORACLE插入数据BUG修复以及获取自增Id支持getLastInsID方法 这些天在做Api接口时候,发现用TP操作Oracle数据库,发现查询修改删除都能执行, 但一旦执行插入操作老是报错 ...

  6. MYSQL获取自增ID的四种方法

    MYSQL获取自增ID的四种方法 1. select max(id) from tablename 2.SELECT LAST_INSERT_ID() 函数 LAST_INSERT_ID 是与tabl ...

  7. YSQL获取自增ID的四种方法(转发)

    YSQL获取自增ID的四种方法(转发) 1. select max(id) from tablename 2.SELECT LAST_INSERT_ID() 函数 LAST_INSERT_ID 是与t ...

  8. DBS-MySQL:MYSQL获取自增ID的四种方法

    ylbtech-DBS-MySQL:MYSQL获取自增ID的四种方法 1.返回顶部 1. 1. select max(id) from tablename 2.SELECT LAST_INSERT_I ...

  9. 查找SQL Server 自增ID值不连续记录

    在很多的时候,我们会在数据库的表中设置一个字段:ID,这个ID是一个IDENTITY,也就是说这是一个自增ID.当并发量很大并且这个字段不是主键的时候,就有可能会让这个值重复:或者在某些情况(例如插入 ...

随机推荐

  1. 使用SqlBulkCopy进行批量插入数据时踩过的坑

    之前一直都没用过SqlBulkCopy关键字进行数据插入,更没了解过. 事因:因业务需要在数据表中添加两列,然后将数据插入进表中 之前都是这样写的 dt.Columns.Add(new DataCol ...

  2. 「SHOI2016」黑暗前的幻想乡

    题目链接 戳我 \(Describe\) \(n−1\)个公司,每个公司能修一些边,求每条边都让不同的公司来修的生成树的方案数 \(Solution\) 这道题很明显容斥.答案就是:所有都选的生成树个 ...

  3. Android源码:(一) 安卓2.1到4.4操作系统通用的Actionbar实现的tab导航例子。

    说一下我在完成这个例子之前的尝试吧 一,修改“actionbarsherlock”的导航例子.我在实现这个例子之前,尝试过“actionbarsherlock”,修改它的一个tab导航的例子,修改成功 ...

  4. adb和adbd详尽分析

    https://blog.csdn.net/viewsky11/article/details/53889143

  5. django2使用xadmin打造适合国人的后台管理系统(1)

    python火了之后,学习python的人也越来越多了,python做web开发的话,flask.django是比较火的框架了,django是一个比较大的框架,也是一个快速开发利器.但是,django ...

  6. View-Controller-Containment

    willMove(toParentViewController:) 调用时机 调用addChildViewController(_:)以钱会被自动调用 调用removeFromParentViewCo ...

  7. 2016级算法第五次上机-E.AlvinZH的学霸养成记IV

    1039 AlvinZH的学霸养成记IV 思路 难题,最大二分图匹配. 难点在于如何转化问题,n对n,一个只能攻击一个,判断是否存在一种攻击方案我方不死团灭对方.可以想到把所有随从看作点,对于可攻击的 ...

  8. 简易APB4 slave实践

    一个简易的(不完整的)APB4 slave的可以没有PREADY和PSLVERR,这两个信号都被赋予常数,以及没有PPROT. 两种不同类型的寄存器: 图: 普通寄存器电路图 图: 带读写控制寄存器电 ...

  9. laravel 运用

    查看路由:php artisan route:list 查看路由

  10. Python爬虫:常用的浏览器请求头User-Agent(转)

    原文地址:https://blog.csdn.net/mouday/article/details/80182397 user_agent = [ "Mozilla/5.0 (Macinto ...