码迷,mamicode.com
首页 > 数据库 > 详细

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

时间:2019-11-12 13:15:25      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:combine   创建   pen   void   执行sql   ams   执行   vat   lse   

一、目前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;
        }
    }
}
技术图片

 

 

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

标签:combine   创建   pen   void   执行sql   ams   执行   vat   lse   

原文地址:https://www.cnblogs.com/zmsoftbj/p/11840947.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!