Entity Framework Code First执行SQL语句、视图及存储过程

2、Entity Framework Code First执行SQL语句

  在使用Entity Framework Code First时,当需要直接执行SQL时,可以使用SqlQuery方法。SqlQuery方法采用属性名即列名的方法进行映射查询,要求返回的查询结果均有完全对应的类属性。

  1>、已定义的表映射类查询

复制代码
复制代码
using (var ctx = new PortalContext())
{
    var provincelist = ctx.Provinces.SqlQuery("SELECT TOP 10 * FROM Province");
    foreach (var province in provincelist)
    {
        Console.WriteLine("{0}-{1}-{2}", province.ProvinceID, province.ProvinceNo, province.ProvinceName);
    }
}
复制代码
复制代码

  2>、未有定义表的临时SQL语句查询

  示例:需要查询Province表中的ProvinceNo,ProvinceName,首先定义一个临时类TempProvince.cs:

复制代码
复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Portal.Models
{
    public class TempProvince
    {
        public string ProvinceNo { get; set; }
        public string ProvinceName { get; set; }
    }
}
复制代码
复制代码

  执行SQL语句查询:

复制代码
复制代码
using (var ctx = new PortalContext())
{
    var provincelist = ctx.Database.SqlQuery<TempProvince>("SELECT TOP 10 ProvinceNo,ProvinceName FROM Province");
    foreach (var province in provincelist)
    {
        Console.WriteLine("{0}-{1}", province.ProvinceNo, province.ProvinceName);
    }
}
复制代码
复制代码

3、Entity Framework Code First执行存储过程

  Entity Framework Code First执行存储过程同样是使用SqlQuery方法。

  创建存储过程:

复制代码
复制代码
CREATE PROCEDURE GetCityByProvinceID
(
    @ProvinceID INT
)
AS
    SELECT * FROM City
    WHERE ProvinceID = @ProvinceID
复制代码
复制代码

  执行存储过程:

复制代码
复制代码
using (var ctx = new PortalContext())
{
    var cityList = ctx.Cities.SqlQuery("dbo.GetCityByProvinceID @p0", 3);
    foreach (var city in cityList)
    {
        Console.WriteLine("{0}-{1}-{2}-{3}", city.CityID, city.ProvinceID, city.CityNo, city.CityName);
    }
}
复制代码
复制代码

  存储过程多个输入参数:

var country = "Australia";
var keyWords = "Beach, Sun";
var destinations = context.Database.SqlQuery<DestinationSummary>("dbo.GetDestinationSummary @p0, @p1", country, keyWords);

 

 

 

Entity Framework是微软出品的高级ORM框架,大多数.NET开发者对这个ORM框架应该不会陌生。本文主要罗列在.NET(ASP.NET/WINFORM)应用程序开发中使用Entity Framework直接执行SQL语句或者存储过程的一些代码片段。具体请见以下正文:

1.使用SqlQuery在已知的实体上执行SQL查询语句

using (var context = new MyDBContext()) 
{ 
    var posts = context.Posts.SqlQuery("SELECT * FROM dbo.Posts").ToList(); 
}

这里的Posts必须是程序项目或者引用中已声明的实体类,ToList()是必须的,否则SQL查询将不会被执行。

注意:如果使用原始的SQL查询语句,请一定要注意处理SQL注入攻击相关的安全问题。

2.使用SqlQuery在已知的实体上执行存储过程

using (var context = new MyDBContext()) 
{ 
    var posts = context.Posts.SqlQuery("dbo.spGetTopPosts").ToList(); 
}

这里的Posts必须是程序项目或者引用中已声明的实体类,ToList()是必须的,否则SQL查询将不会被执行。以上代码将执行存储过程: spGetTopPosts

3.使用SqlQuery在已知实体上执行带参数的存储过程

using (var context = new MyDBContext()) 
{ 
    var postID = 99; 
    var posts = context.Posts.SqlQuery("dbo.spGetTopPosts @p0", postID).Single(); 
}

这里的Posts必须是程序项目或者引用中已声明的实体类,Single()是必须的,否则SQL查询将不会被执行。以上代码将执行存储过程: spGetTopPosts,并带一个传入参数postID

4.使用SqlQuery在未知实体上执行SQL查询语句

using (var context = new MyDBContext()) 
{ 
    var postTitles = context.Database.SqlQuery<string>("SELECT Title FROM dbo.Posts").ToList(); 
}

5.使用SqlQuery执行带参数的SQL查询语句

这是一种相比更安全的,可避免SQL注入攻击的执行原始SQL查询语句的方式

using (var context = new MyDBContext()) 
{ 
    var userSuppliedAuthor = new SqlParameter("@author", "Adi");
    context.Database.SqlQuery(typeof(Post), "SELECT * FROM dbo.Posts WHERE Author = @author", userSuppliedAuthor);
}

这里的SQL语句将查询Posts表,所以用到了typeof(Post)。如果JOIN语句来查询不同的两张表的话,就需要写一个内部类来返回SQL语句的查询结果。

以下则是一个使用JOIN连接查询的具体实例。

假如有Posts,Category,Posts_Category这三张表。Posts_Category是Post表中Post Id列以及Category表中Category Id列的映射表。如果我们执行如下的JOIN连接SQL查询:

复制代码
复制代码
internal class MappingData
{
    public string CategoryTitle { get; set; }
    public string PostTitle { get; set; }
    public long? MappingId { get; set; }
}

using (var context = new MyDBContext())
{
    var userSuppliedId = new SqlParameter("@PostId", PostID);
    string sqlQuery = @"select c.Name CategoryTitle, pcm.Id MappingId, p.Title PostTitle from Posts_Categories pcm 
    join Categories c on pcm.CategoryId = c.Id
    join Posts p on pcm.PostId = p.Id where pcm.PostId =@PostId";
    var Results = db.Database.SqlQuery<MappingData>(sqlQuery,userSuppliedId).ToList();
}
复制代码
复制代码

查询结果将是所有给定Post的Categories列表。

6.使用ExcuteSqlCommand在未知实体上执行更新操作

using (var context = new MyDBContext()) 
{ 
    context.Database.ExecuteSqlCommand( "UPDATE dbo.Posts SET Title = 'Updated Title' WHERE PostID = 99"); 
}

总结:以上的SqlQuery和ExecuteSqlCommand方法均是DbContext对应数据库实例的方法,如果是执行原始的未经处理的SQL语句时,请一定注意SQL注入攻击等安全性问题!!!


 

7. 存储过程

7.1 示例(1)

create proc pro_Add
@i int,
@j int,
@he int output
as
set @he = @i+@j
复制代码
复制代码
System.Data.SqlClient.SqlParameter[] parameters2 = { 
                                                  new System.Data.SqlClient.SqlParameter("@i",100),
                                                  new System.Data.SqlClient.SqlParameter("@j",100),
                                                  new System.Data.SqlClient.SqlParameter("@he", System.Data.SqlDbType.Int)
                                                  };
parameters2[2].Direction = System.Data.ParameterDirection.Output;
System.Data.Common.DbCommand cmd = DbContext.Database.Connection.CreateCommand();
cmd.CommandText = "pro_Add";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddRange(parameters2);
if (cmd.Connection.State != System.Data.ConnectionState.Open)
    cmd.Connection.Open();
cmd.ExecuteNonQuery();
string output1 = parameters2[2].Value.ToString();
cmd.Connection.Close();
string output2 = parameters2[2].Value.ToString();
复制代码
复制代码

7.2 示例(2)

复制代码
复制代码
create proc pro_Add
@i int,
@j int,
@he int output
as
set @he = @i+@j
select @he
go
复制代码
复制代码
复制代码
复制代码
System.Data.SqlClient.SqlParameter[] parameters = { 
                                                  new System.Data.SqlClient.SqlParameter("@i",100),
                                                  new System.Data.SqlClient.SqlParameter("@j",100),
                                                  new System.Data.SqlClient.SqlParameter("@he", System.Data.SqlDbType.Int)
                                                  };
parameters[2].Direction = System.Data.ParameterDirection.Output;
var slt = this.DbContext.Database.SqlQuery<int>("exec pro_Add @i,@j,@he output", parameters);
slt.ToList();
int AllCount = Int32.Parse(parameters[2].Value.ToString());
复制代码
复制代码

 


8. 执行SQL语句

 

复制代码
复制代码
//示例1.
System.Data.SqlClient.SqlParameter[] parameters = { };
var slt = this.DbContext.Database.SqlQuery(typeof(BadWordFilter),"select top 100 * from BadWordFilter", parameters);
foreach( var item in slt )
{
    BadWordFilter badword = item as BadWordFilter;
    string word = badword.badWordContent;
}

//示例2.
System.Data.SqlClient.SqlParameter[] parameters = { new System.Data.SqlClient.SqlParameter("@id",ID)};
var slt = this.DbContext.Database.SqlQuery<BadWordFilter>("select top 1 * from BadWordFilter where badWordID=@id", parameters);
BadWordFilter item = slt.First();

//示例3.
System.Data.SqlClient.SqlParameter[] parameters = { };
var slt = this.DbContext.Database.SqlQuery<int>("select count(*) from BadWordFilter", parameters);
int AllCount = slt.First();
复制代码
复制代码

posted on   大西瓜3721  阅读(275)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2017-01-24 微信网页第三方登录原理

导航

点击右上角即可分享
微信分享提示