Entity Framework中执行sql语句

一、为什么要在EF中执行SQL语句

使用EF操作数据库,可以避免写SQL语句,完成使用Linq实现,但为什么还要在EF中执行SQL语句呢。如果要写SQL语句,完全可以使用ADO.NET来操作数据库。这样说虽然没错,可是有些时候使用EF操作数据库还是有一些不方便的地方,例如:如果要修改某一条记录,按照EF的正常流程走,需要先把要修改的数据查询出来,然后在去修改,这样不仅麻烦而且性能也低,这时直接使用EF执行SQL语句性能会提高很多。
而使用EF执行SQL又比ADO.NET方便,特别是在执行查询语句的时候,EF会把查询到的数据自动保存到数据实体中,省去了使用DataReader的麻烦。同时查询出来的数据还会进行跟踪,如果你修改了查询出的值,之后就可以很方便的使用.SaveChanges()直接更新到数据库了。
在数据上下文DbContext中有一个Database的属性,Database属性中有两组方法:ExecuteSqlCommand()和SqlQuery()。这两个方法都可以用来执行SQL语句,但这两个方法也有不同点:ExecuteSqlCommand()是不返回结果的,只返回受影响的行数,所以ExecuteSqlCommand()更适合用来执行创建、插入、更新、删除操作(即执行给定的DDL/DML命令)。SqlQuery()则会返回查询到的结果,并将结果保存在数据实体中,所以SqlQuery()更适合执行查询操作。

二、使用ExecuteSqlCommand()执行创建、插入、更新、删除语句

ExecuteSqlCommand()的使用方法很简单,直接传入SQL语句就可以了,执行完成后会返回受影响的行数。
在下面的例子中,entity是一个继承自DbContext的对象。

1、执行创建语句

// 执行创建语句
string strCreateSQL = @"CREATE table test( id int primary key not null,name varchar(16),password varchar(20))";
 // 注意:执行create语句受影响的行数是-1
int result = entity.Database.ExecuteSqlCommand(strCreateSQL);
if (result.Equals(-1))
{
    Console.WriteLine("创建成功!");
}

2、执行Insert语句

// 执行Insert语句
string strInsertSQL = @"INSERT INTO test
                                        SELECT 1,'小明','1234' UNION
                                        SELECT 2,'小王','1234' UNION
                                        SELECT 3,'小红','1234'  ";
int result = entity.Database.ExecuteSqlCommand(strInsertSQL);
if (result > 0)
{
       Console.WriteLine("插入成功");
}

3、执行Update语句

// 执行Update语句
string strUpdateSQL = @"UPDATE test SET password=@pwd1 WHERE id=@id1;
UPDATE test SET password=@pwd2 WHERE id=@id2;";
                SqlParameter[] para =  {
                   new  SqlParameter("@pwd1","ceshi12we"),
                   new  SqlParameter("@id1",1),
                   new  SqlParameter("@pwd2","ceshi127890"),
                   new  SqlParameter("@id2",2),
                };

int result = entity.Database.ExecuteSqlCommand(strUpdateSQL, para);
if (result > 0)
{
    Console.WriteLine("更新成功");
}

4、执行Delete语句

// 执行删除语句
string strDelSQL = "delete from test";
int result = entity.Database.ExecuteSqlCommand(strDelSQL);
if (result > 0)
{
     Console.WriteLine("删除成功");
}

5、执行Drop语句

string strDropSQL = "drop table test";
int result = entity.Database.ExecuteSqlCommand(strDropSQL);
if (result.Equals(-1))
{
    Console.WriteLine("删除成功");
}

注意:执行DDL语句(create、alter、drop等)返回值是-1,DML(insert、update、delete)返回的是受影响的行数。

三、使用SqlQuery()查询数据

SqlQuery()是用来执行查询的。SqlQuery()使用前需要指定返回值的类型。返回值类型可以是定义的实体类型,或者基元类型。例如:查询一个用户的完整信息,返回类型就是用户实体类型;如果是统计有多少个用户,返回值就是int类型。
注意:返回值的个数和名称必须和传入的类型中属性个数、名称相同,不如会报错。

在下面的例子中User是根据数据库表生成的实体类型。

string strSQL = "SELECT * FROM Users WHERE ID>=10 ORDER BY ID DESC";
var info = entity.Database.SqlQuery<User>(strSQL);
foreach (var item in info)
{
       Console.WriteLine("ID:" + item.ID + " " + "登录名:" + item.LoginName + " " + "密码:" + item.Password);
}

运行结果:

前面说过返回值的个数和名称必须和传入的类型中属性个数、名称相同,不如会报错。如果将SQL语句修改为只查询ID、登录名、密码会出现下面的错误:

如果只想查询ID、登录名、密码该怎么办呢?那就需要单独定义一个类(只包含ID、登录名、密码三个属性)来保存数据.

新定义的类,只包含ID、登录名、密码三个属性:

public class newUser
{
        public int ID { get; set; }

        public string LoginName { get; set; }

        public string Password { get; set; }
}
// 方法四:SqlQuery
try
{
                string strSQL = "SELECT ID,LoginName,Password FROM Users WHERE ID>=10 ORDER BY ID DESC";
                var info = entity.Database.SqlQuery<newUser>(strSQL);
                foreach (var item in info)
                {
                    Console.WriteLine("ID:" + item.ID + " " + "登录名:" + item.LoginName + " " + "密码:" + item.Password);
                }
}
catch (Exception ex)
{
                Console.WriteLine(ex.Message);
}

运行结果:

返回值是基元类型:

查询用户数量,返回int类型

// 查询用户数量
string strSQL = "SELECT COUNT(*) FROM test";
var result = entity.Database.SqlQuery<int>(strSQL);
// 注意:必须使用循环才会真正的去数据库执行SQL语句,否则不会再数据库执行SQL语句(EF的延迟加载)
foreach(var item in result)
{
     Console.WriteLine("用户数量:" + item.ToString());
}

运行结果:

四、使用DbSet<T>下的SqlQuery()

在每个数据实体集合DbSet<T>下也有一个SqlQuery(),功能与上面介绍的一样,只不过DbSet<T>下的SqlQuery()只能返回DbSet<T>中包含的类型,DbSet<T>下的SqlQuery()在返回数据的同时还会让数据库上下文(DBContext)跟踪返回数据的状态,如果返回的数据发生了修改,就可以使用SaveChanges()将结果直接保存回数据库。而Database.SqlQuery()查出的结果则不能跟踪返回数据的状态。

1、使用实体集合下面的SqlQuery()方法

string strSQL = "SELECT * FROM Users WHERE UserID='002068'";
User user = entity.Users.SqlQuery(strSQL).FirstOrDefault();
user.Password = "测试实体下面的SqlQuery方法";
// 调用SaveChanges()方法可以更新Password字段
entity.SaveChanges();

2、使用Database下的SqlQuery()方法

string strSQL = "SELECT * FROM Users WHERE UserID='002068'";
User user = entity.Database.SqlQuery<User>(strSQL).FirstOrDefault();
user.Password = "测试Database下面的SqlQuery方法";
// 调用SaveChanges()方法不可以更新Password字段
entity.SaveChanges();

如果希望使用Database下的SqlQuery()查询出的数据在修改后也能保存到数据库,可以使用下面的代码:

string strSQL = "SELECT * FROM Users WHERE UserID='002068'";
User user = entity.Database.SqlQuery<User>(strSQL).FirstOrDefault();
user.Password = "测试Database下面的SqlQuery方法";
// 设置这条数据的状态是:Modified,这样可以通知数据上下文,这条记录也被修改了
entity.Entry<User>(user).State = System.Data.Entity.EntityState.Modified;
// 调用SaveChanges()方法不可以更新Password字段
entity.SaveChanges();

到此这篇关于Entity Framework中执行sql语句的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Entity Framework Core中执行SQL语句和存储过程的方法介绍

    无论ORM有多么强大,总会出现一些特殊的情况,它无法满足我们的要求.在这篇文章中,我们介绍几种执行SQL的方法. 表结构 在具体内容开始之前,我们先简单说明一下要使用的表结构. public class Category { public int CategoryID { get; set; } public string CategoryName { get; set; } } 在Category定义了两个字段:CategoryID.CategoryName. public class Sam

  • Entity Framework Core延迟加载(懒加载)用法

    众所周知在EF 6 及以前的版本中,是支持懒加载(Lazy Loading)的,可惜在EF Core 并不支持,必须使用Include方法来支持导航属性的数据加载.不过现在EF Core的开发团队打算恢复对这一功能的支持(目前还未发布,不过可以在Github上面下载进行测试). 懒加载 懒加载也可以叫做按需加载.延迟加载.可以分两方面来理解,一方面指暂时不需要该数据,不用在当前马上加载,而可以推迟到使用它时再加载:另一方面指不确定是否将会需要该数据,所以暂时请不要加载,待确定需要后再加载它.懒加

  • Entity Framework常用查询语句

    方法一:Linq to Entitie var info = from p in entity.Users where p.ID >= 10 orderby p.ID descending select p; foreach (var item in info) { Console.WriteLine("ID:" + item.ID + " " + "登录名:" + item.LoginName + " " + &quo

  • Entity Framework系统架构与原理介绍

    一.Entity Framework概要 Entity Framework是微软的Object Relational Mapper(对象关系映射),也就是我们平常说的ORM,它可以让应用程序开发者将关系型数据作为业务模型来使用,也消除了开发者为数据访问编写的绝大多数管道代码的需要(比如使用ADO.NET).Entity Framework提供了一个综合的.基于模型的系统,通过摆脱为所有的领域模型编写相似的数据访问代码,使得开发者创建数据访问层是如此之简单.Entity Framework的首发版

  • Entity Framework Core实现Like查询详解

    在Entity Framework Core 2.0中增加一个很酷的功能:EF.Functions.Like(),最终解析为SQL中的Like语句,以便于在 LINQ 查询中直接调用. 不过Entity Framework 中默认提供了StartsWith.Contains和EndsWith方法用于解决模糊查询,那么为什么还要提供EF.Functions.Like,今天我们来重点说说它们之间的区别. 表结构定义 在具体内容开始之前,我们先简单说明一下要使用的表结构. public class C

  • Entity Framework Core实现软删除与查询过滤器

    注意:我使用的是 Entity Framework Core 2.0 (2.0.0-preview2-final).正式版发布后,功能可能存在变动. 继续探索Entity Framework Core 2.0,今天我将探讨如何轻松使用软删除(或逻辑删除).我的意思是以透明的方式实现软删除,例如,您是物理上的删除行. 要实现软删除,您需要添加一列以指示该行数据是否被逻辑删除.如果您想知道该行被删除,可以使用布尔列,如果您想知道删除的时间,可以使用日期列.其次是更改所有查询,使用此列过滤结果集:您还

  • Entity Framework Core批处理SQL语句

    在Entity Framework Core (EF Core)有许多新的功能,最令人期待的功能之一就是批处理语句.那么批处理语句是什么呢?批处理语句意味着它不会为每个插入/更新/删除语句发送单独的请求,它将在数据库的单次请求中批量执行多个语句.在这篇文章中,让我们看看它是如何工作的,并将结果与EF6进行比较. EF Core将一次准备多个语句,然后在单次请求中执行它们,所以能提供了更好的性能和速度.让我们看看它是如何工作的.我们将借助SQL Server Profiler来捕获实际生成和执行的

  • Entity Framework Core生成列并跟踪列记录

    注意:我使用的是 Entity Framework Core 2.0 (2.0.0-preview2-final).正式版发布时,功能可能存在变动. 当您设计数据库时,有时需要添加列以跟踪记录何时更改,以及谁进行了更改.例如,您添加以下列: CreatedAt CreatedBy LastUpdatedAt LastUpdatedBy 您可以轻松地使用默认值和触发器来处理CreatedAt和LastUpdatedAt列.老实说,创建触发器是件无聊的事情,你也不想自己做.此外,很难设置用户名,因为

  • Entity Framework中执行sql语句

    一.为什么要在EF中执行SQL语句 使用EF操作数据库,可以避免写SQL语句,完成使用Linq实现,但为什么还要在EF中执行SQL语句呢.如果要写SQL语句,完全可以使用ADO.NET来操作数据库.这样说虽然没错,可是有些时候使用EF操作数据库还是有一些不方便的地方,例如:如果要修改某一条记录,按照EF的正常流程走,需要先把要修改的数据查询出来,然后在去修改,这样不仅麻烦而且性能也低,这时直接使用EF执行SQL语句性能会提高很多.而使用EF执行SQL又比ADO.NET方便,特别是在执行查询语句的

  • Shell脚本中执行sql语句操作mysql的5种方法

    对于自动化运维,诸如备份恢复之类的,DBA经常需要将SQL语句封装到shell脚本.本文描述了在Linux环境下mysql数据库中,shell脚本下调用sql语句的几种方法,供大家参考.对于脚本输出的结果美化,需要进一步完善和调整.以下为具体的示例及其方法. 1.将SQL语句直接嵌入到shell脚本文件中 复制代码 代码如下: --演示环境  [root@SZDB ~]# more /etc/issue  CentOS release 5.9 (Final)  Kernel \r on an \

  • Oracle基础:通过sqlplus执行sql语句后的结果进行判断

    这篇文章介绍一下如何对sqlplus执行的sql语句结果进行判断. 环境准备 使用Oracle的精简版创建docker方式的demo环境,详细可参看: https://www.jb51.net/article/153533.htm 常见问题 在sqlplus中执行sql语句,如果直接使用命令行的方式调用时会碰到两个问题: 问题1: 需要进行交互性的输入 问题2:结果的判断不能通过返回值来确认 解决方式 在脚本调用里,解决方式如下 问题1可以通过前文提到的Here Document来解决. 问题2

  • Navicat Premium操作MySQL数据库(执行sql语句)

    一. Navicat 简介 1. 什么是Navicat ? Navicat是一个强大的MySQL数据库管理和开发工具.Navicat为专业开发者提供了一套强大的足够尖端的工具,但它对于新用户仍然是易于学习.Navicat,使用了极好的图形用户界面(GUI),可以让你用一种安全和更为容易的方式快速和容易地创建.组织.存取和共享信息.用户可完全控制 MySQL 数据库和显示不同的管理资料,包括一个多功能的图形化管理用户和访问权限的管理工具,方便将数据从一个数据库移转到另一个数据库中(Local to

  • 在MySQL数据库中使用C执行SQL语句的方法

    他们将讨论返回数据的语句,例如INSERT以及不返回数据的语句,例如UPDATE和DELETE.然后,他们将编写从数据库检索数据的简单程序 执行SQL语句 现在,我们已经有了一个连接,并且知道如何处理错误,是时候讨论使用我们的数据库来作一些实际工作了.执行所有类型的SQL的主关键字是mysql_query: int mysql_query(MYSQL *connection, const char *query) 正如您所见,它非常简单.它取一个指向连接结构的指针和包含要执行的SQL的文本字符串

  • 如何让docker中的mysql启动时自动执行sql语句

    在用docker创建mysql容器的时,有时候我们期望容器启动后数据库和表已经自动建好,初始化数据也已自动录入,也就是说容器启动后我们就能直接连上容器中的数据库,使用其中的数据了. 其实mysql的官方镜像是支持这个能力的,在容器启动的时候自动执行指定的sql脚本或者shell脚本,我们一起来看看mysql官方镜像的Dockerfile,如下图: 已经设定了ENTRYPOINT,里面会调用/entrypoint.sh这个脚本,我们把mysql:8这个镜像pull到本地,再用docker run启

  • .Net core下直接执行SQL语句并生成DataTable的实现方法

    .net core可以执行SQL语句,但是只能生成强类型的返回结果.例如var blogs = context.Blogs.FromSql("SELECT * FROM dbo.Blogs").ToList().而不允许返回DataSet.DataTable等弱类型.可能由于这个原因没有实现在.net core中DataTable,然而DataTable还是可能会用到的.我们这里就有一个数据仓库的需求,允许用户自行编写类似SQL语句,然后执行,以表格展示.因为语句是千变万化的,因此我也

  • 在Java的Hibernate框架中使用SQL语句的简单介绍

    Hibernate中有HQL查询语法.但我们用得比较熟的还是数SQL语句,那么应该怎么来让Hibernate支持SQL呢?这个不用我们去考虑了,Hibernate团队已经早就做好了.        废话不说,直接来例子啦. select * from t_user usr 上面是一条SQL语句,又是废话,是个人都知道.我们想让Hibernate执行这条语句,怎么办呢?看代码: Query query = session.createSQLQuery("select * from t_user u

随机推荐