zoukankan      html  css  js  c++  java
  • C# EF使用SqlQuery直接操作SQL查询语句或者存储过程

    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();
  • 相关阅读:
    为什么全局变量一定要初始化?
    SecureCRT 使用密钥登录 Ubuntu
    ubuntu samba 服务器搭建
    Linux 软硬链接的区别及目录权限对软硬链接的影响
    【转载】解析 java 按值传递还是按引用传递
    (转)如何学好C语言
    (转)五个方法成为更好的程序员
    (转)SQLite数据库的加密
    鸟哥Linux私房菜(基础篇)——第十一章:认识与学习Bash
    鸟哥Linux私房菜(基础篇)——第五章:首次登入与在线求助 man page笔记
  • 原文地址:https://www.cnblogs.com/zhaoshujie/p/10694188.html
Copyright © 2011-2022 走看看