zoukankan      html  css  js  c++  java
  • 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;
            }
        }
    }
    View Code

     更多:

    .NetCore中EFCore的使用整理

    .NetCore中EFCore的使用整理(二)-关联表查询

     .NetCore中EFCore for MySql整理(三)之Pomelo.EntityFrameworkCore.MySql

  • 相关阅读:
    设计模式学习笔记——Bridge 桥接模式
    设计模式学习笔记——Adapter 适配器模式
    protoc protobuff安装
    docker-compose启动consul
    docker etcd 环境搭建
    nifi的去重方案设计(二)-外部存储mysql全局去重
    实现一套ES全文检索语法-到Lucene语法的转换工具,以实现在es外部兼容处理文本分词
    nifi的去重方案设计(一)-单队列内去重.md
    k8s 证书过期处理
    部分项目从kafka迁移至pulsar,近期使用中碰到了一些问题,勉强把大的坑踩完了,topic永驻,性能相关
  • 原文地址:https://www.cnblogs.com/tianma3798/p/10025009.html
Copyright © 2011-2022 走看看