Entity Framework(EF) 直接执行数据库命令并返回 DataTable 数据参数化 SQL 语句

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

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

 

1

2

3

4

using (var context = new MyDBContext())

{

    var posts = context.Posts.SqlQuery("SELECT * FROM dbo.Posts").ToList();

}

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

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

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

 

1

2

3

4

using(varcontext=newMyDBContext())

{

    varposts=context.Posts.SqlQuery("dbo.spGetTopPosts").ToList();

}

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

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

 

1

2

3

4

5

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查询语句

 

1

2

3

4

using(varcontext=newMyDBContext())

{

    varpostTitles=context.Database.SqlQuery<string>("SELECT Title FROM dbo.Posts").ToList();

}

 

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

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

1

2

3

4

5

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查询:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

internalclassMappingData

{

  publicstringCategoryTitle{get;set;}

  publicstringPostTitle{get;set;}

  publiclong?MappingId{get;set;}

}

using(varcontext=newMyDBContext())

{

varuserSuppliedId=newSqlParameter("@PostId",PostID);

stringsqlQuery=@"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";

varResults=db.Database.SqlQuery<MappingData>(sqlQuery,userSuppliedId).ToList();

}

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

取输出参数的值

  1. using (RPDBContext db = new RPDBContext())

  2. {

  3. try

  4. {

  5. db.Database.ExecuteSqlCommand("EXEC [AddVote] @blockId,@titleId,@typeId,@num out", paramArray.ToArray());

  6. }

  7. catch (Exception ex)

  8. {

  9. throw;

  10. }

  11. int result = (int)paramArray[3].Value;

  12. return result;

  13. }

  14.  

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

 

1

2

3

4

5

using(varcontext=newMyDBContext())

{

      context.Database.ExecuteSqlCommand(

        "UPDATE dbo.Posts SET Title = 'Updated Title' WHERE PostID = 99");

}

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

 

 

 

    //以下是一些常用调用方法

        private void button1_Click(object sender, EventArgs e)
        {
            string id = "1";
            string sql = "select * from table1 where id = @id";


            #region mysql数据库参数类型
            var args = new DbParameter[] {
                                      new SqlParameter { ParameterName = "id", Value = id},
                                  };
            #endregion


            #region mysql数据库参数类型
            //var args = new DbParameter[] {
            //                          new OdbcParameter { ParameterName = "id", Value = id},
            //                      };


       //     var args = new DbParameter[] {
       //                               new MySqlParameter { ParameterName = "id", Value = "1"},
       //                 };
            #endregion


            #region access数据库参数类型
            //var args = new DbParameter[] {
            //                          new OleDbParameter { ParameterName = "id", Value = id},
            //                      };
            #endregion
            MessageBox.Show(SqlQuery<h_job>(sql, args).Count().ToString());

 

        }

 

 

扩展方法如下:
        /// <summary>
        /// 执行带参数sql语句返回数据列表
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="sql">sql语句</param>
        /// <param name="args">参数</param>
        /// <returns>数据列表</returns>
        public List<T> SqlQuery<T>(string sql, DbParameter[] args)
        {
            if (string.IsNullOrEmpty(sql))
                return new List<T>();
            try
            {
                using (itlogo_integralEntities db = new itlogo_integralEntities())
                {
                    return db.Database.SqlQuery<T>(sql, args).ToList();
                }
            }
            catch (Exception ex)
            {
                return new List<T>();
            }
        }
        /// <summary>
        /// 执行不带参数sql语句返回数据列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <returns></returns>
        public static List<T> SqlQuery<T>(string sql)
        {
            if (string.IsNullOrEmpty(sql))
                return new List<T>();
            try
            {
                using (itlogo_integralEntities db = new itlogo_integralEntities())
                {
                    return db.Database.SqlQuery<T>(sql).ToList();
                }
            }
            catch (Exception ex)
            {
                return new List<T>();
            }
        }
        /// <summary>
        /// 执行带参数sql语句返回受影响行数
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static int ExecuteSqlCommand(string sql, DbParameter[] args)
        {
            if (string.IsNullOrEmpty(sql))
                return 0;
            try
            {
                using (itlogo_integralEntities db = new itlogo_integralEntities())
                {
                    return db.Database.ExecuteSqlCommand(sql, args);
                }
            }
            catch (Exception ex)
            {
                return 0;
            }
        }
        /// <summary>
        /// 执行sql语句返回收影响行数
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>

 

        public static int ExecuteSqlCommand(string sql)       {
            if (string.IsNullOrEmpty(sql))
                return 0;
            try
            {
                using (itlogo_integralEntities db = new itlogo_integralEntities())
                {
                    return db.Database.ExecuteSqlCommand(sql);
                }
            }
            catch (Exception ex)
            {
                return 0;
            }
        }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值