EF Core中执行Sql语句查询操作之FromSql,ExecuteSqlCommand,SqlQuery

一、目前EF Core的版本为V2.1

相比较EF Core v1.0 目前已经增加了不少功能。

EF Core除了常用的增删改模型操作,Sql语句在不少项目中是不能避免的。

在EF Core中上下文,可以返货DbConnection ,执行sql语句。这是最底层的操作方式,代码写起来还是挺多的。

初次之外 EF Core中还支持 FromSql,ExecuteSqlCommand 连个方法,用于更方便的执行Sql语句。

另外,目前版本的EF Core 不支持SqlQuery,但是我们可以自己扩展一个。坐等升级以后支持吧。

1.FromSql,执行列表查询

public static IQueryable<TEntity> FromSql<TEntity>([NotNullAttribute] this IQueryable<TEntity> source, 
[NotParameterized] RawSqlString sql,
[NotNullAttribute] params object[] parameters) where TEntity : class;

这种方式,仅用于当前上线文中注册的 模型对象。

对于上下文DbSet<T>中没有定义的不起作用。

示例代码1:

    //执行sql查询语句 FromSql()
   QLLB_SWXContext _Context = new QLLB_SWXContext();
   string sql = "select * from Article where CategoryID=1;";
   List<Article> list = _Context.Article.FromSql(sql).ToList();
   foreach (var item in list)
  {
       Console.WriteLine(item.Title);
  }

示例代码2:视图中的查询

---创建视图,查询没有分配角色的菜单
create view view_NoRole
as
select * from Sys_Navigation
where NavID not in (
select distinct  NavID   from Sys_Role_Nav
)
//查询视图
   string sql2 = "select * from view_NoRole";
   List<SysNavigation> roleList = _Context.SysNavigation.FromSql(sql2).ToList();
   foreach (var item in roleList)
  {
       Console.WriteLine(item.Title);
  }

2.ExecuteSqlCommand,执行Sql操作处理

QLLB_SWXContext _Context = new QLLB_SWXContext();
//执行数据操作sql,返回受影响的行数
string sql = "update Sys_Role set SortValue=1 ;";
int count = _Context.Database.ExecuteSqlCommand(sql);
Console.WriteLine(count);

3.自定义SqlQuery,执行列表查询,在上线文中不存的对象。

示例代码1:

QLLB_SWXContext _Context = new QLLB_SWXContext();
//特别说明,自定义分装的不支持 单个值查询
//不支持object 查询
//自定义查询操作 SqlQuery
string sql = "select sum(ViewCount)*1.11 as allCount from Article;";
TempData result = _Context.Database.SqlQuery<TempData>(sql).FirstOrDefault();
Console.WriteLine(result.AllCount);

对象定义

public class TempData
{
   public int CategoryID { get; set; }
   public string Title { get; set; }
   public int ArtCount { get; set; }
   /// <summary>
   /// 求和结果
   /// </summary>
   public decimal AllCount { get; set; }
}

示例代码2:

执行视图查询:

--定义视图,文章分类和对应分类的文章数量
create view view_CateCount
as
select C.CategoryID,C.Title, (
select count(*) from Article where CategoryID=C.CategoryID
) as ArtCount  from ArticleCategory C;

C#代码:

//组合查询
string sql2 = "select * from view_CateCount;";
List<TempData> tempList = _Context.Database.SqlQuery<TempData>(sql2).ToList();
foreach (var item in tempList)
{
   Console.WriteLine(item.Title);
}

SqlQuery扩展定义:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Reflection;
using System.Text;

namespace QL.Card.Entity
{
   public static class DbContextExtensions
  {
       private static void CombineParams(ref DbCommand command, params object[] parameters)
      {
           if (parameters != null)
          {
               foreach (SqlParameter parameter in parameters)
              {
                   if (!parameter.ParameterName.Contains("@"))
                       parameter.ParameterName = $"@{parameter.ParameterName}";
                   command.Parameters.Add(parameter);
              }
          }
      }

       private static DbCommand CreateCommand(DatabaseFacade facade, string sql, out DbConnection dbConn, params object[] parameters)
      {
           DbConnection conn = facade.GetDbConnection();
           dbConn = conn;
           conn.Open();
           DbCommand cmd = conn.CreateCommand();
           if (facade.IsSqlServer())
          {
               cmd.CommandText = sql;
               CombineParams(ref cmd, parameters);
          }
           return cmd;
      }

       public static DataTable SqlQuery(this DatabaseFacade facade, string sql, params object[] parameters)
      {
           DbCommand cmd = CreateCommand(facade, sql, out DbConnection conn, parameters);
           DbDataReader reader = cmd.ExecuteReader();
           DataTable dt = new DataTable();
           dt.Load(reader);
           reader.Close();
           conn.Close();
           return dt;
      }

       public static IEnumerable<T> SqlQuery<T>(this DatabaseFacade facade, string sql, params object[] parameters) where T : class, new()
      {
           DataTable dt = SqlQuery(facade, sql, parameters);
           return dt.ToEnumerable<T>();
      }

       public static IEnumerable<T> ToEnumerable<T>(this DataTable dt) where T : class, new()
      {
           PropertyInfo[] propertyInfos = typeof(T).GetProperties();
           T[] ts = new T[dt.Rows.Count];
           int i = 0;
           foreach (DataRow row in dt.Rows)
          {
               T t = new T();
               foreach (PropertyInfo p in propertyInfos)
              {
                   if (dt.Columns.IndexOf(p.Name) != -1 && row[p.Name] != DBNull.Value)
                       p.SetValue(t, row[p.Name], null);
              }
               ts[i] = t;
               i++;
          }
           return ts;
      }
  }
}
技术交流Q群: 1012481075 群内有各种流行书籍资料
原文链接:https://w.cnblogs.com/tianma3798/p/10025009.html

发表评论

您的电子邮箱地址不会被公开。

WeChat
WeChat
QQ
QQ
返回顶部