zoukankan      html  css  js  c++  java
  • 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();
    复制代码
  • 相关阅读:
    nginx 学习
    java 数组转字符串(以逗号分隔开)
    索引命名规范
    java常见的设计模式
    java中的堆、栈浅解。
    Oracle忘记System密码怎么办?
    端口被占用,怎么解决?
    Spring Mvc学习之路
    svg了解一下
    推荐几款基于vue的使用插件
  • 原文地址:https://www.cnblogs.com/Alex80/p/8344010.html
Copyright © 2011-2022 走看看