entityframework学习笔记--009-使用原生sql语句操作数据
1 使用原生SQL语句更新--Database.ExecuteSqlCommand
假设你有一张如图9-1所示的Payment数据库表。

图9-1
1.1 实体类型:
public class Payment
{
public int PaymentId { get; set; }
public decimal Amount { get; set; } public string Vendor { get; set; }
}
1.2 数据访问类:
public class EF6RecipesContext: DbContext
{
public DbSet<Payment> Payments { get; set; }
public EF6RecipesContext()
: base("name=EF6CodeFirstRecipesContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder); modelBuilder.Entity<Payment>().ToTable("Payments", "example9");
}
}
1.3 代码演示:
// 删除之前的测试数据
using (var context = new EFRecipesEntities())
{
context.Database.ExecuteSqlCommand("delete from chapter3.payment");
}
//插入两行数据
using (var context = new EFRecipesEntities())
{
var sql = @"insert into Chapter3.Payment(Amount, Vendor)
values (@Amount, @Vendor)"; //这里可以使用@p0这样的参数占位符,ado.net为自动为我们创建参数对象
var parameters = new DbParameter[]
{
new SqlParameter {ParameterName = "Amount", Value = 99.97M},
new SqlParameter {ParameterName = "Vendor", Value = "Ace Plumbing"}
}; var rowCount = context.Database.ExecuteSqlCommand(sql, parameters); parameters = new DbParameter[]
{
new SqlParameter {ParameterName = "Amount", Value = 43.83M},
new SqlParameter
{
ParameterName = "Vendor",
Value = "Joe's Trash Service"
}
}; rowCount += context.Database.ExecuteSqlCommand(sql, parameters);
Console.WriteLine("{0} rows inserted", rowCount.ToString());
} // 获取并显示数据
using (var context = new EFRecipesEntities())
{
Console.WriteLine("Payments");
Console.WriteLine("========");
foreach (var payment in context.Payments)
{
Console.WriteLine("Paid {0} to {1}", payment.Amount.ToString(),
payment.Vendor);
}
} Console.WriteLine("\nPress <enter> to continue...");
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
public class EFRecipesEntities : DbContext
{
public EFRecipesEntities()
: base("ConnectionString")
{
} public DbSet<Student> Students { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>().ToTable("example9.Students");
base.OnModelCreating(modelBuilder);
}
}
2.3 代码演示:
using (var context = new EFRecipesEntities())
{
// 删除出测试数据
context.Database.ExecuteSqlCommand("delete from example9.students"); // 插入数据
context.Students.Add(new Student
{
FirstName = "Robert",
LastName = "Smith",
Degree = "Masters"
});
context.Students.Add(new Student
{
FirstName = "Julia",
LastName = "Kerns",
Degree = "Masters"
});
context.Students.Add(new Student
{
FirstName = "Nancy",
LastName = "Stiles",
Degree = "Doctorate"
});
context.SaveChanges();
} using (var context = new EFRecipesEntities())
{
var sql = "select * from example9.Students where Degree = @Major";
var parameters = new DbParameter[]
{
new SqlParameter {ParameterName = "Major", Value = "Masters"}
};
var students = context.Database.SqlQuery<Student>(sql, parameters);
Console.WriteLine("Students...");
foreach (var student in students)
{
Console.WriteLine("{0} {1} is working on a {2} degree",
student.FirstName, student.LastName, student.Degree);
}
} Console.WriteLine("\nPress <enter> to continue...");
Console.ReadLine();
}
输出:
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语句。
entityframework学习笔记--009-使用原生sql语句操作数据的更多相关文章
- power desinger 学习笔记三<批量执行sql语句>
使用sql脚本导入表结构,直接 附带表的 约束.列的注释.真的可以哦 sql语句如下: create table test01 ( ID VARCHAR2(10 ...
- MyBatis学习 之 三、动态SQL语句
目录(?)[-] 三动态SQL语句 selectKey 标签 if标签 if where 的条件判断 if set 的更新语句 if trim代替whereset标签 trim代替set choose ...
- 执行原生SQL语句的方式
原生sql语句 cursor方法:from api.models import *from django.db import connection,connectionscursor=connecti ...
- orm分组,聚合查询,执行原生sql语句
from django.db.models import Avg from app01 import models annotate:(聚合查询) ret=models.Article.objects ...
- Django中使用mysql数据库并使用原生sql语句操作
Django自身默认使用sqlite3这个轻量级的数据库,但是当我们开发网站时,sqlite3就没有mysql好,sqlite3适合一些手机上开发使用的数据库. 准备的软件mysql数据库,版本5.7 ...
- 05: MySQLdb 原生SQL语句操作数据库
1.1 MySQLdb安装与简介 1.MySQLdb 模块的安装(python3中目前这个模块还不可用)参考博客 1. linux: yum install MySQL-python 2. windo ...
- django系列5.4--ORM中执行原生SQL语句, Python脚本中调用django环境
ORM执行原生sql语句 在模型查询API不够用的情况下,我们还可以使用原始的SQL语句进行查询. Django 提供两种方法使用原始SQL进行查询:一种是使用raw()方法,进行原始SQL查询并返回 ...
- 在Hibernate中使用原生SQL语句
使用原生SQL查询必须注意:程序必须选出所有的数据列才可被转换成持久化实体.假设实体在映射时有一个<many-to-one../>的关联指向另外一个实体,则SQL查询中必须返回该<m ...
- 2016/05/13 thinkphp 3.2.2 ① 数据删除及执行原生sql语句 ②表单验证
[数据删除及执行原生sql语句] delete() 返回受影响的记录条数 $goods -> delete(30); 删除主键值等于30的记录信息 $goods -> delete( ...
随机推荐
- BPM与 SAP & Oracle EBS集成解决方案分享
一.需求分析 SAP和Oracle EBS都是作为全球顶级的的ERP产 品,得到了众多客户的青睐.然而由于系统庞大.价格昂贵以及定位不同,客户在实施过程中经常会面临以下困惑: 1.SAP如何实现&qu ...
- PMON failed to acquire latch, see PMON dump
前几天,一台Oracle数据库(Oracle Database 10g Release 10.2.0.4.0 - 64bit Production)监控出现"PMON failed to a ...
- 【译】Meteor 新手教程:在排行榜上添加新特性
原文:http://danneu.com/posts/6-meteor-tutorial-for-fellow-noobs-adding-features-to-the-leaderboard-dem ...
- .Net深入实战系列—JSON序列化那点事儿
序 当前主流的序列化JSON字符串主要有两种方式:JavaScriptSerializer及Json.net(Nuget标识:Newtonsoft.Json).JavaScriptSerializer ...
- ABP框架 - 会话
文档目录 本节内容: 简介 关于 IAbpSeesion 注入会话 会话属性 用户标识符 简介 如果一个应用需要登录,它就需要知道当前用户在执行的操作.尽管Asp.net自身在展现层提供了Sessio ...
- npm常用命令
npm常用命令 环境:win7 npm 是什么 NPM(node package manager),通常称为node包管理器.顾名思义,它的主要功能就是管理node包,包括:安装.卸载.更新.查看.搜 ...
- 06.GitHub实战系列~6.过滤器过滤掉的文件如何上传
比如我想发布一个软件版本供普通人下载: Git库建立了VS的过滤规则后 dll 和 exe 是自动过滤的,这时候我们得加参数(看图)git add xxx -f
- 【Win10 应用开发】集成文件打开选择器
有朋友给老周提出建议:老周,能不能在写博客时讲一下有深度的小故事?技术文章谁不会写.讲一下对人生有启发性的故事会更好. 哎呀,这要求真是越来越高了.好吧,尽量吧,如果有小故事的话,老周在就每次写博客时 ...
- 浅析MySQL基于ROW格式的二进制日志
上文分析的二进制日志实际上是基于STATEMENT格式的,下面我们来看看基于ROW格式的二进制日志,毕竟,两者对应的binlog事件类型也不一样,同时,很多童鞋反映基于ROW格式的二进制日志无法查到原 ...
- 读书笔记--SQL必知必会19--存储过程
不同的DBMS对存储过程的实现不同,差异巨大,这里不涉及具体的DBMS,仅仅说明存储过程的简单含义. 19.1 存储过程 简单来说,存储过程就是为以后使用而保存的一条或多条SQL语句. 可以将存储过程 ...