entityframework学习笔记--009-使用原生sql语句操作数据

1 使用原生SQL语句更新--Database.ExecuteSqlCommand

假设你有一张如图9-1所示的Payment数据库表。

图9-1

1.1 实体类型:

1  public class Payment
2     {
3         public int PaymentId { get; set; }
4         public decimal Amount { get; set; }
5
6         public string Vendor { get; set; }
7     }

1.2 数据访问类:

 1 public class EF6RecipesContext: DbContext
 2     {
 3         public DbSet<Payment> Payments { get; set; }
 4         public EF6RecipesContext()
 5             : base("name=EF6CodeFirstRecipesContext")
 6         {
 7         }
 8         protected override void OnModelCreating(DbModelBuilder modelBuilder)
 9         {
10             base.OnModelCreating(modelBuilder);
11
12             modelBuilder.Entity<Payment>().ToTable("Payments", "example9");
13         }
14     }

1.3 代码演示:

 1 // 删除之前的测试数据
 2             using (var context = new EFRecipesEntities())
 3             {
 4                 context.Database.ExecuteSqlCommand("delete from chapter3.payment");
 5             }
 6             //插入两行数据
 7             using (var context = new EFRecipesEntities())
 8             {
 9                 var sql = @"insert into Chapter3.Payment(Amount, Vendor)
10                    values (@Amount, @Vendor)";    //这里可以使用@p0这样的参数占位符,ado.net为自动为我们创建参数对象
11                 var parameters = new DbParameter[]
12                     {
13                         new SqlParameter {ParameterName = "Amount", Value = 99.97M},
14                         new SqlParameter {ParameterName = "Vendor", Value = "Ace Plumbing"}
15                     };
16
17                 var rowCount = context.Database.ExecuteSqlCommand(sql, parameters);
18
19                 parameters = new DbParameter[]
20                     {
21                         new SqlParameter {ParameterName = "Amount", Value = 43.83M},
22                         new SqlParameter
23                             {
24                                 ParameterName = "Vendor",
25                                 Value = "Joe‘s Trash Service"
26                             }
27                     };
28
29                 rowCount += context.Database.ExecuteSqlCommand(sql, parameters);
30                 Console.WriteLine("{0} rows inserted", rowCount.ToString());
31             }
32
33             // 获取并显示数据
34             using (var context = new EFRecipesEntities())
35             {
36                 Console.WriteLine("Payments");
37                 Console.WriteLine("========");
38                 foreach (var payment in context.Payments)
39                 {
40                     Console.WriteLine("Paid {0} to {1}", payment.Amount.ToString(),
41                                       payment.Vendor);
42                 }
43             }
44
45             Console.WriteLine("\nPress <enter> to continue...");
46             Console.ReadLine();

输出:

1 2 rows inserted
2 Payments
3 ========
4 Paid $99.97 to Ace Plumbing
5 Paid $43.83 to Joe‘s Trash Service

2 使用原生SQL语句获取对象--Database.SqlQuery()

假设你有如图所示的一个拥有Student实体类型的模型。

2.1 实体类型

public class Student
    {
        public int StudentId { get; set; }
        public string Degree { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

2.2 上下文对象DbContext

 1 public class EFRecipesEntities : DbContext
 2     {
 3         public EFRecipesEntities()
 4             : base("ConnectionString")
 5         {
 6         }
 7
 8         public DbSet<Student> Students { get; set; }
 9
10         protected override void OnModelCreating(DbModelBuilder modelBuilder)
11         {
12             modelBuilder.Entity<Student>().ToTable("example9.Students");
13             base.OnModelCreating(modelBuilder);
14         }
15     }

2.3 代码演示:

 1 using (var context = new EFRecipesEntities())
 2             {
 3                 // 删除出测试数据
 4                 context.Database.ExecuteSqlCommand("delete from example9.students");
 5
 6                 // 插入数据
 7                 context.Students.Add(new Student
 8                     {
 9                         FirstName = "Robert",
10                         LastName = "Smith",
11                         Degree = "Masters"
12                     });
13                 context.Students.Add(new Student
14                     {
15                         FirstName = "Julia",
16                         LastName = "Kerns",
17                         Degree = "Masters"
18                     });
19                 context.Students.Add(new Student
20                     {
21                         FirstName = "Nancy",
22                         LastName = "Stiles",
23                         Degree = "Doctorate"
24                     });
25                 context.SaveChanges();
26             }
27
28             using (var context = new EFRecipesEntities())
29             {
30                 var sql = "select * from example9.Students where Degree = @Major";
31                 var parameters = new DbParameter[]
32                     {
33                         new SqlParameter {ParameterName = "Major", Value = "Masters"}
34                     };
35                 var students = context.Database.SqlQuery<Student>(sql, parameters);
36                 Console.WriteLine("Students...");
37                 foreach (var student in students)
38                 {
39                     Console.WriteLine("{0} {1} is working on a {2} degree",
40                                       student.FirstName, student.LastName, student.Degree);
41                 }
42             }
43
44             Console.WriteLine("\nPress <enter> to continue...");
45             Console.ReadLine();
46         }

输出:

 Students...
 Robert Smith is working on a Masters degree
 Julia Kerns is working on a Masters degree

这里在查询语句中使用“*”表示所有的列名,实体框架会将返回的列匹配到合适的属性上。一般情况下,这会工作得很好。但是,查询中只有部分列返回时,实体框架会在实例化对象时抛出一个异常。一个更好的方法和最佳实践是,在你的查询语句中显式枚举所有列(也就是说,指定所有的列名)。

  如果你的SQL语句返回的列多于实例化实体所需数量(也就是说,列值数量多于实体对象属性数量),实体框架会忽略掉多于的列。如果你仔细想想,这不是一个令人满意的行为。再一次重申,在SQL语句中显式枚举你所期望返回的列名,确保它们与实体类型匹配

  SqlQuery()方法有很多限制,如果你在使用TPH继承映射,你的SQL语句返回的行要映射到不同的派生类型上,实体框架不能使用鉴别列来将行映射到正确的派生类型。你可能会得到一个运行时异常,因为行中可能不包含正在实例化类型所需的值。

  有趣的是,我们可以使用SqlQuery()方法实例化根本就不是实体的类型。例如,我们创建一个StudentName类,它只包含姓,和名两个属性民。如果我们的SQL语句也只返回这两个列,我们可以使用SqlQuery<StudentName>()方法和指定的SQL语句获取类型StudentName的实例集合。

  我们很小心地使用短语,SQL语句,而不是查询语句,是因为SqlQuery()方法可以接受任何返回行集合的SQL语句。这当然包含查询语句,但也包含执行存储过程的SQL语句。

 
时间: 2024-10-26 19:30:12

entityframework学习笔记--009-使用原生sql语句操作数据的相关文章

Oracle学习笔记之第八节sql语句(开发课学生指南051)

开发课 做练习 学生指南051 les01 ppt oracle经常两表连接,叫第三范式,如带有ID性质的东西 以下是sql语句的命令 select * from departments; 部门表 select * from employees; 员工表 select employee_id,rowid,rownum from employees where employee_id>=200;  64进制内部运算 rownum本质查询第几行 select employee_id,rowid,ro

数据库学习笔记3--基本的SQL语句

[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4028178.html [正文] 主要内容: 一.cmd命令行的常用命令 二.数据定义语言(DDL) 三.数据操纵语言(DML) 四.数据查询语言(DRL) 五.事务控制语言(TCL) 一.cmd命令行的常用命令: 当我们使用MySQL 5.5 Command Line Client这个客户端登陆时

Oracle 学习笔记 17 -- 异常处理(PL/SQL)

程序在执行过程中出现异常是正常的,在程序的编写过程中出现异常也是不可避免的.但是要有相应的异常处理的机 制,来保证程序的正常执行.PL/SQL程序执行过程中出现的错误,称为异常.一个优秀的程序都应该能够正确处理 各种出错的情况,并尽可能的从错误中恢复.PL/SQL提供了异常处理机制. 概念: 异常处理(exception)是用来处理正常执行过程中未预料的事件,程序块的异常处理定义的错误和自定义的错误, 由于PL/SQL程序块一旦产生异常而没有指出如何处理时,程序就会异常的终止. 有三种类型的错误

python学习笔记七:条件&循环语句

1.print/import更多信息 print打印多个表达式,使用逗号隔开 >>> print 'Age:',42 Age: 42   #注意个结果之间有一个空格符 import:从模块导入函数 import 模块 from 模块 import 函数 from 模块 import * 如果两个模块都有open函数的时候, 1)使用下面方法使用: module1.open()... module2.open()... 2)语句末尾增加as子句 >>> import ma

在Hibernate中使用原生SQL语句

使用原生SQL查询必须注意:程序必须选出所有的数据列才可被转换成持久化实体.假设实体在映射时有一个<many-to-one../>的关联指向另外一个实体,则SQL查询中必须返回该<many-to-one../>映射的外键列,否则将导致抛出"column not found"异常.最简单的做法是,在SQL字符串中使用星(*)来表示返回所有列.    在原生SQL语句中一样支持使用参数,这些参数即可使用问号参数(?),也可使用名字参数. 示例1:名字参数public

MyBatis学习 之 三、动态SQL语句

有些时候,sql语句where条件中,需要一些安全判断,例如按某一条件查询时如果传入的参数是空,此时查询出的结果很可能是空的,也许我们需要参数为空时,是查出全部的信息.使用Oracle的序列.mysql的函数生成Id.这时我们可以使用动态sql. 下文均采用mysql语法和函数(例如字符串链接函数CONCAT). 3.1 selectKey 标签 在insert语句中,在Oracle经常使用序列.在MySQL中使用函数来自动生成插入表的主键,而且需要方法能返回这个生成主键.使用myBatis的s

django 使用原生SQL语句反向生成MODELS.PY中的表结构

在一次工作中,有这么一个问题,就是要导入的数据字段不确定,但是还想使用django的ORM来对数据进行操作.. 琢磨了许久,弄个不完善的方案,但功能是能实现的,主要是思路.废话不多说了,丑陋的展示一下吧... from django.db import connection #粗陋的用数组和字符串表示一下要导入的数据表单项lis = ['ll', 'bb', 'yy'] #表示要建立的表单字段l = 'tablename' #表名ll = 'fff' new_table = connection

******用SQL语句操作数据*******

用SQL语句操作数据 01.SQL语句书写规范 1,.在SQL Sever中,SQL语句不区分大小写(数据库名,表名,列名,关键字) ,SQL编译器都识别 2,对表进行操作的时候,一定要使先用use关键字切换到对应的数据库 3.自增列不可以赋值 02.新增数据注意事项 01.如果新增全部列,那么表名后可以不跟列名,但是要提供所有列的值,除非当前 列有默认值,那么也要给出default关键字. 02.如果只想给一张表中添加部分列,那么在表名后要跟上列名,并且需要保证除了你给出 的列的值之外,其他列

一些经典===&gt;&gt;用SQL语句操作数据

用SQL语句操作数据 结构化查询语言(Structured Query Language)简称SQL(发音:/?es kju? ?el/ "S-Q-L"),是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库系统:同时也是数据库脚本文件的扩展名. 01.SQL语句书写规范 1.在SQL Sever中,SQL语句不区分大小写(数据库名,表名,列名,关键字) ,SQL编译器都识别 2.对表进行操作的时候,一定要使先用use关键字切换到对应的数