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.Linq;
using System.Reflection;
using System.Text;

namespace Som.Common
{
    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;
        }
        /// <summary>
        /// 执行SQL返回受影响的行数
        /// </summary>
        public static int ExecSqlNoQuery<T>(this DatabaseFacade facade, string sql, SqlParameter[] sqlParams = null) where T : new()
        {
            return facade.ExecuteNoQuery<T>( sql, sqlParams);
        }
        /// <summary>
        /// 执行存储过程返回IEnumerable数据集
        /// </summary>
        public static IEnumerable<T> ExecProcReader<T>(this DatabaseFacade facade, string sql, SqlParameter[] sqlParams = null) where T : new()
        {
            return facade.Execute<T>( sql, CommandType.StoredProcedure, sqlParams);
        }
        /// <summary>
        /// 执行sql返回IEnumerable数据集
        /// </summary>
        public static IEnumerable<T> ExecSqlReader<T>(this DatabaseFacade facade, string sql, SqlParameter[] sqlParams = null) where T : new()
        {
            return facade.Execute<T>(sql,CommandType.Text, sqlParams);
        }
        /// <summary>
        /// 执行SQL 返回受影响的行数 用于update delete 等
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="facade"></param>
        /// <param name="sql"></param>
        /// <param name="sqlParams"></param>
        /// <returns></returns>
        private static int ExecuteNoQuery<T>(this DatabaseFacade facade, string sql, SqlParameter[] sqlParams) where T : new()
        {
            DbCommand cmd = CreateCommand(facade, sql, out DbConnection conn, sqlParams);
            int result = 0;            
            cmd.CommandText = sql;
            cmd.CommandType = CommandType.Text;
            if (sqlParams != null)
            {
                cmd.Parameters.AddRange(sqlParams);
            }
            result = cmd.ExecuteNonQuery();
            conn.Close();
            return result;
        }
        private static IEnumerable<T> Execute<T>(this DatabaseFacade facade, string sql, CommandType type, SqlParameter[] parameters) where T : new()
        {
            
            DbCommand cmd = CreateCommand(facade, sql, out DbConnection conn, parameters);            
            cmd.CommandText = sql;
            cmd.CommandType = type;
            if (parameters != null)
            {
                cmd.Parameters.AddRange(parameters);
            }
            DataTable dt = new DataTable();
            using (DbDataReader reader = cmd.ExecuteReader())
            {
                dt.Load(reader);
            }
            conn.Close();
            return dt.ToCollection<T>();
        }
        /// <summary>
        /// DataTable和集合的扩展
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static IEnumerable<T> ToCollection<T>(this DataTable dt) where T : new()
        {
            if (dt == null || dt.Rows.Count == 0)
            {
                return Enumerable.Empty<T>();
            }
            IList<T> ts = new List<T>();
            // 获得此模型的类型 
            Type type = typeof(T);
            string tempName = string.Empty;
            foreach (DataRow dr in dt.Rows)
            {
                T t = new T();
                PropertyInfo[] propertys = t.GetType().GetProperties();
                foreach (PropertyInfo pi in propertys)
                {
                    tempName = pi.Name;
                    //检查DataTable是否包含此列(列名==对象的属性名)     
                    if (dt.Columns.Contains(tempName))
                    {
                        // 判断此属性是否有Setter   
                        if (!pi.CanWrite) continue;//该属性不可写,直接跳出   
                        object value = dr[tempName];
                        if (value != DBNull.Value)
                            //pi.SetValue(t, value, null);
                            pi.SetValue(t, StrHelper.ConvertType(value, pi.PropertyType), null);
                    }
                }
                ts.Add(t);
            }
            return ts;
        }

        /// <summary>
        /// 执行SQL 返回DataTable
        /// </summary>
        /// <param name="facade"></param>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        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;
        }
        /// <summary>
        /// 执行SQL 返回 IEnumerable<T>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="facade"></param>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        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;
            //定义一个临时变量  存放属性名称
            string tempName = string.Empty;
            foreach (DataRow row in dt.Rows)
            {
                T t = new T();
                foreach (PropertyInfo p in propertyInfos)
                {
                    tempName = p.Name;//将属性名称赋值给临时变量  
                    //检查DataTable是否包含此列(列名==对象的属性名) 
                    string tpye1 = p.PropertyType.ToString();
                    if (dt.Columns.IndexOf(p.Name) != -1 && row[p.Name] != DBNull.Value)
                    {
                        // 判断此属性是否有Setter  
                        if (!p.CanWrite) continue;//该属性不可写,直接跳出  
                        object value = row[tempName];
                        p.SetValue(t, StrHelper.ConvertType(value, p.PropertyType), null);
                    }
                }
                ts[i] = t;
                i++;
            }
            return ts;
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Som.Common
{
    /// <summary>
    /// 字符串操作 - 工具方法
    /// </summary>
    public static partial class StrHelper
    {
        #region Empty(空字符串)

        /// <summary>
        /// 空字符串
        /// </summary>
        public static string Empty
        {
            get { return string.Empty; }
        }

        /// <summary>
        /// 判断这个Object是否为空
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsEmpty(object obj)
        {
            if (obj == null)
            {
                return true;
            }
            else if (obj.ToString() == "")
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// 将obj转换为Type类型
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static object ConvertType(object obj, Type t)
        {
            if (obj == null || obj.ToString() == "")
            {
                return null;
            }

            string tpye1 = t.ToString();
            if (tpye1.IndexOf("System.String") != -1)
            {
                return Convert.ToString(obj);
            }
            else if (tpye1.IndexOf("System.Int32") != -1)
            {
                if (obj.ToString().ToLower()=="true")
                {
                    obj = "1";
                }
                else if (obj.ToString().ToLower() == "false")
                {
                    obj = "0";
                }
                return Convert.ToInt32(obj);
            }
            else if (tpye1.IndexOf("System.Int64") != -1)
            {
                
                return Convert.ToInt64(obj);
            }
            else if (tpye1.IndexOf("System.DateTime") != -1)
            {
                if (StrHelper.IsNumber(obj.ToString()))
                {
                    return Convert.ToDateTime(Convert.ToDouble(obj));
                }
                else
                {
                    return Convert.ToDateTime(obj);
                }
            }
            else if (tpye1.IndexOf("System.Boolean") != -1)
            {
                if (obj.ToString() == "")
                {
                    obj = true;
                }
                else if (obj.ToString() == "")
                {
                    obj = false;
                }

                return Convert.ToBoolean(obj);
            }
            else if (tpye1.IndexOf("System.Decimal") != -1)
            {
                return Convert.ToDecimal(obj);
            }
            else if (tpye1.IndexOf("System.Double") != -1)
            {
                return Convert.ToDouble(obj);
            }

            //else if (tpye1.IndexOf("System.Collections.Generic.ICollection`1") != -1)
            //{
            //    string Type = tpye1.Replace("System.Collections.Generic.ICollection`1[Model.", "").Replace("]", "");
            //    using (var context = new MESContext())
            //    {
            //        var postTitles = context.Database.SqlQuery<string>("SELECT ID FROM dbo." + Type + "s where ID in (" + obj.ToString() + ")").ToList();
            //        return postTitles;
            //    }
            //}
            return obj;
        }

        #endregion

        #region PinYin(获取汉字的拼音简码)

        /// <summary>
        /// 获取汉字的拼音简码,即首字母缩写,范例:中国,返回zg
        /// </summary>
        /// <param name="chineseText">汉字文本,范例: 中国</param>
        public static string PinYin(string chineseText)
        {
            if (string.IsNullOrWhiteSpace(chineseText))
                return string.Empty;
            var result = new StringBuilder();
            foreach (char text in chineseText)
                result.AppendFormat("{0}", ResolvePinYin(text));
            return result.ToString().ToLower();
        }

        /// <summary>
        /// 解析单个汉字的拼音简码
        /// </summary>
        /// <param name="text">单个汉字</param>
        private static string ResolvePinYin(char text)
        {
            byte[] charBytes = Encoding.Default.GetBytes(text.ToString());
            if (charBytes[0] <= 127)
                return text.ToString();
            var unicode = (ushort) (charBytes[0] * 256 + charBytes[1]);
            string pinYin = ResolvePinYinByCode(unicode);
            if (!string.IsNullOrWhiteSpace(pinYin))
                return pinYin;
            return ResolvePinYinByFile(text.ToString());
        }

        /// <summary>
        /// 使用字符编码方式获取拼音简码
        /// </summary>
        private static string ResolvePinYinByCode(ushort unicode)
        {
            if (unicode >= '\uB0A1' && unicode <= '\uB0C4')
                return "A";
            if (unicode >= '\uB0C5' && unicode <= '\uB2C0' && unicode != 45464)
                return "B";
            if (unicode >= '\uB2C1' && unicode <= '\uB4ED')
                return "C";
            if (unicode >= '\uB4EE' && unicode <= '\uB6E9')
                return "D";
            if (unicode >= '\uB6EA' && unicode <= '\uB7A1')
                return "E";
            if (unicode >= '\uB7A2' && unicode <= '\uB8C0')
                return "F";
            if (unicode >= '\uB8C1' && unicode <= '\uB9FD')
                return "G";
            if (unicode >= '\uB9FE' && unicode <= '\uBBF6')
                return "H";
            if (unicode >= '\uBBF7' && unicode <= '\uBFA5')
                return "J";
            if (unicode >= '\uBFA6' && unicode <= '\uC0AB')
                return "K";
            if (unicode >= '\uC0AC' && unicode <= '\uC2E7')
                return "L";
            if (unicode >= '\uC2E8' && unicode <= '\uC4C2')
                return "M";
            if (unicode >= '\uC4C3' && unicode <= '\uC5B5')
                return "N";
            if (unicode >= '\uC5B6' && unicode <= '\uC5BD')
                return "O";
            if (unicode >= '\uC5BE' && unicode <= '\uC6D9')
                return "P";
            if (unicode >= '\uC6DA' && unicode <= '\uC8BA')
                return "Q";
            if (unicode >= '\uC8BB' && unicode <= '\uC8F5')
                return "R";
            if (unicode >= '\uC8F6' && unicode <= '\uCBF9')
                return "S";
            if (unicode >= '\uCBFA' && unicode <= '\uCDD9')
                return "T";
            if (unicode >= '\uCDDA' && unicode <= '\uCEF3')
                return "W";
            if (unicode >= '\uCEF4' && unicode <= '\uD188')
                return "X";
            if (unicode >= '\uD1B9' && unicode <= '\uD4D0')
                return "Y";
            if (unicode >= '\uD4D1' && unicode <= '\uD7F9')
                return "Z";
            return string.Empty;
        }

        /// <summary>
        /// 从拼音简码文件获取
        /// </summary>
        /// <param name="text">单个汉字</param>
        private static string ResolvePinYinByFile(string text)
        {
            int index = Const.ChinesePinYin.IndexOf(text, StringComparison.Ordinal);
            if (index < 0)
                return string.Empty;
            return Const.ChinesePinYin.Substring(index + 1, 1);
        }

        #endregion

        #region Splice(拼接集合元素)

        /// <summary>
        /// 拼接集合元素
        /// </summary>
        /// <typeparam name="T">集合元素类型</typeparam>
        /// <param name="list">集合</param>
        /// <param name="quotes">引号,默认不带引号,范例:单引号 "'"</param>
        /// <param name="separator">分隔符,默认使用逗号分隔</param>
        public static string Splice<T>(IEnumerable<T> list, string quotes = "", string separator = ",")
        {
            if (list == null)
                return string.Empty;
            var result = new StringBuilder();
            foreach (var each in list)
                result.AppendFormat("{0}{1}{0}{2}", quotes, each, separator);
            return result.ToString().TrimEnd(separator.ToCharArray());
        }

        #endregion

        #region FirstUpper(将值的首字母大写)

        /// <summary>
        /// 将值的首字母大写
        /// </summary>
        /// <param name="value"></param>
        public static string FirstUpper(string value)
        {
            string firstChar = value.Substring(0, 1).ToUpper();
            return firstChar + value.Substring(1, value.Length - 1);
        }

        #endregion

        #region ToCamel(将字符串转成驼峰形式)

        /// <summary>
        /// 将字符串转成驼峰形式
        /// </summary>
        /// <param name="value">原始字符串</param>
        public static string ToCamel(string value)
        {
            return FirstUpper(value.ToLower());
        }

        #endregion

        #region ContainsChinese(是否包含中文)

        /// <summary>
        /// 是否包含中文
        /// </summary>
        /// <param name="text">文本</param>
        public static bool ContainsChinese(string text)
        {
            const string pattern = "[\u4e00-\u9fa5]+";
            return Regex.IsMatch(text, pattern);
        }

        #endregion

        #region ContainsNumber(是否包含数字)

        /// <summary>
        /// 是否包含数字
        /// </summary>
        /// <param name="text">文本</param>
        public static bool ContainsNumber(string text)
        {
            const string pattern = "[0-9]+";
            return Regex.IsMatch(text, pattern);
        }

        #endregion

        #region Distinct(去除重复)

        /// <summary>
        /// 去除重复
        /// </summary>
        /// <param name="value">值,范例1:"5555",返回"5",范例2:"4545",返回"45"</param>
        public static string Distinct(string value)
        {
            var array = value.ToCharArray();
            return new string(array.Distinct().ToArray());
        }

        #endregion

        #region Truncate(截断字符串)

        /// <summary>
        /// 截断字符串
        /// </summary>
        /// <param name="text">文本</param>
        /// <param name="length">返回长度</param>
        /// <param name="endCharCount">添加结束符号的个数,默认0,不添加</param>
        /// <param name="endChar">结束符号,默认为省略号</param>
        public static string Truncate(string text, int length, int endCharCount = 0, string endChar = ".")
        {
            if (string.IsNullOrWhiteSpace(text))
                return string.Empty;
            if (text.Length < length)
                return text;
            return text.Substring(0, length) + GetEndString(endCharCount, endChar);
        }

        /// <summary>
        /// 获取结束字符串
        /// </summary>
        private static string GetEndString(int endCharCount, string endChar)
        {
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < endCharCount; i++)
                result.Append(endChar);
            return result.ToString();
        }

        #endregion

        #region Unique(获取全局唯一值)

        /// <summary>
        /// 获取全局唯一值
        /// </summary>
        public static string Unique()
        {
            return Guid.NewGuid().ToString().Replace("-", "");
        }

        #endregion

        public static bool IsNumber(string strNumber)
        {
            Regex objNotNumberPattern = new Regex("[^0-9.-]");
            Regex objTwoDotPattern = new Regex("[0-9]*[.][0-9]*[.][0-9]*");
            Regex objTwoMinusPattern = new Regex("[0-9]*[-][0-9]*[-][0-9]*");
            String strValidRealPattern = "^([-]|[.]|[-.]|[0-9])[0-9]*[.]*[0-9]+$";
            String strValidIntegerPattern = "^([-]|[0-9])[0-9]*$";
            Regex objNumberPattern = new Regex("(" + strValidRealPattern + ")|(" + strValidIntegerPattern + ")");

            return !objNotNumberPattern.IsMatch(strNumber) &&
                   !objTwoDotPattern.IsMatch(strNumber) &&
                   !objTwoMinusPattern.IsMatch(strNumber) &&
                   objNumberPattern.IsMatch(strNumber);
        }

        /// <summary>
        /// 将字符串格式化成指定的数据类型
        /// </summary>
        /// <param name="str"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static object Format(this string str, Type type)
        {
            if (String.IsNullOrEmpty(str))
                return null;
            if (type == null)
                return str;
            if (type.IsArray)
            {
                Type elementType = type.GetElementType();
                String[] strs = str.Split(new char[] {';'});
                Array array = Array.CreateInstance(elementType, strs.Length);
                for (int i = 0, c = strs.Length; i < c; ++i)
                {
                    array.SetValue(ConvertSimpleType(strs[i], elementType), i);
                }

                return array;
            }

            return ConvertSimpleType(str, type);
        }

        private static object ConvertSimpleType(object value, Type destinationType)
        {
            object returnValue;
            if ((value == null) || destinationType.IsInstanceOfType(value))
            {
                return value;
            }

            string str = value as string;
            if ((str != null) && (str.Length == 0))
            {
                return null;
            }

            TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
            bool flag = converter.CanConvertFrom(value.GetType());
            if (!flag)
            {
                converter = TypeDescriptor.GetConverter(value.GetType());
            }

            if (!flag && !converter.CanConvertTo(destinationType))
            {
                throw new InvalidOperationException("无法转换成类型:" + value.ToString() + "==>" + destinationType);
            }

            try
            {
                returnValue = flag
                    ? converter.ConvertFrom(null, null, value)
                    : converter.ConvertTo(null, null, value, destinationType);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("类型转换出错:" + value.ToString() + "==>" + destinationType, e);
            }

            return returnValue;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="s"></param>
        /// <param name="d">默认值</param>
        /// <returns></returns>
        public static string ToString(this decimal? s, string d)
        {
            return s.ToString(0, d);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="s"></param>
        /// <param name="s">小数保留位数</param>
        /// <param name="d">默认值</param>
        /// <returns></returns>
        public static string ToString(this decimal? s, int i, string d)
        {
            if (!s.HasValue)
                return d;
            return s.Value.ToString("f" + i);
        }

        /// <summary>
        /// 获取中英文混排字符串的实际长度(字节数)
        /// </summary>
        /// <param name="str">要获取长度的字符串</param>
        /// <returns>字符串的实际长度值(字节数)</returns>
        public static int GetStringLength(string str)
        {
            if (str.Equals(string.Empty))
                return 0;
            int strlen = 0;
            ASCIIEncoding strData = new ASCIIEncoding();
            //将字符串转换为ASCII编码的字节数字
            byte[] strBytes = strData.GetBytes(str);
            for (int i = 0; i <= strBytes.Length - 1; i++)
            {
                if (strBytes[i] == 63) //中文都将编码为ASCII编码63,即"?"号
                    strlen++;
                strlen++;
            }

            return strlen;
        }

        /// <summary>
        /// 查找字符串第N次位置
        /// </summary>
        /// <param name=""></param>
        /// <param name=""></param>
        /// <param name=""></param>
        /// <returns></returns>
        //参数:字符串,要查找的字符串值,要查找第几个该字符串值
        public static int GetStrFindIndexToN(string str, string cha, int num)
        {
            var x = str.IndexOf(cha);
            for (var i = 0; i < num - 1; i++) //从第0位开始,NUM需要-1
            {
                x = str.IndexOf(cha, x + 1);
            }
            if (x==-1)
            {
                x = str.Length;
            }
            return x;
        }
    }
}

 

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.Linq;using System.Reflection;using System.Text;
namespace Som.Common{    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;        }        /// <summary>        /// 执行SQL返回受影响的行数        /// </summary>        public static int ExecSqlNoQuery<T>(this DatabaseFacade facade, string sql, SqlParameter[] sqlParams = null) where T : new()        {            return facade.ExecuteNoQuery<T>( sql, sqlParams);        }        /// <summary>        /// 执行存储过程返回IEnumerable数据集        /// </summary>        public static IEnumerable<T> ExecProcReader<T>(this DatabaseFacade facade, string sql, SqlParameter[] sqlParams = null) where T : new()        {            return facade.Execute<T>( sql, CommandType.StoredProcedure, sqlParams);        }        /// <summary>        /// 执行sql返回IEnumerable数据集        /// </summary>        public static IEnumerable<T> ExecSqlReader<T>(this DatabaseFacade facade, string sql, SqlParameter[] sqlParams = null) where T : new()        {            return facade.Execute<T>(sql,CommandType.Text, sqlParams);        }        /// <summary>        /// 执行SQL 返回受影响的行数 用于update delete 等        /// </summary>        /// <typeparam name="T"></typeparam>        /// <param name="facade"></param>        /// <param name="sql"></param>        /// <param name="sqlParams"></param>        /// <returns></returns>        private static int ExecuteNoQuery<T>(this DatabaseFacade facade, string sql, SqlParameter[] sqlParams) where T : new()        {            DbCommand cmd = CreateCommand(facade, sql, out DbConnection conn, sqlParams);            int result = 0;                        cmd.CommandText = sql;            cmd.CommandType = CommandType.Text;            if (sqlParams != null)            {                cmd.Parameters.AddRange(sqlParams);            }            result = cmd.ExecuteNonQuery();            conn.Close();            return result;        }        private static IEnumerable<T> Execute<T>(this DatabaseFacade facade, string sql, CommandType type, SqlParameter[] parameters) where T : new()        {                        DbCommand cmd = CreateCommand(facade, sql, out DbConnection conn, parameters);                        cmd.CommandText = sql;            cmd.CommandType = type;            if (parameters != null)            {                cmd.Parameters.AddRange(parameters);            }            DataTable dt = new DataTable();            using (DbDataReader reader = cmd.ExecuteReader())            {                dt.Load(reader);            }            conn.Close();            return dt.ToCollection<T>();        }        /// <summary>        /// DataTable和集合的扩展        /// </summary>        /// <typeparam name="T"></typeparam>        /// <param name="dt"></param>        /// <returns></returns>        public static IEnumerable<T> ToCollection<T>(this DataTable dt) where T : new()        {            if (dt == null || dt.Rows.Count == 0)            {                return Enumerable.Empty<T>();            }            IList<T> ts = new List<T>();            // 获得此模型的类型             Type type = typeof(T);            string tempName = string.Empty;            foreach (DataRow dr in dt.Rows)            {                T t = new T();                PropertyInfo[] propertys = t.GetType().GetProperties();                foreach (PropertyInfo pi in propertys)                {                    tempName = pi.Name;                    //检查DataTable是否包含此列(列名==对象的属性名)                         if (dt.Columns.Contains(tempName))                    {                        // 判断此属性是否有Setter                           if (!pi.CanWrite) continue;//该属性不可写,直接跳出                           object value = dr[tempName];                        if (value != DBNull.Value)                            //pi.SetValue(t, value, null);                            pi.SetValue(t, StrHelper.ConvertType(value, pi.PropertyType), null);                    }                }                ts.Add(t);            }            return ts;        }
        /// <summary>        /// 执行SQL 返回DataTable        /// </summary>        /// <param name="facade"></param>        /// <param name="sql"></param>        /// <param name="parameters"></param>        /// <returns></returns>        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;        }        /// <summary>        /// 执行SQL 返回 IEnumerable<T>        /// </summary>        /// <typeparam name="T"></typeparam>        /// <param name="facade"></param>        /// <param name="sql"></param>        /// <param name="parameters"></param>        /// <returns></returns>        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;            //定义一个临时变量  存放属性名称            string tempName = string.Empty;            foreach (DataRow row in dt.Rows)            {                T t = new T();                foreach (PropertyInfo p in propertyInfos)                {                    tempName = p.Name;//将属性名称赋值给临时变量                      //检查DataTable是否包含此列(列名==对象的属性名)                     string tpye1 = p.PropertyType.ToString();                    if (dt.Columns.IndexOf(p.Name) != -1 && row[p.Name] != DBNull.Value)                    {                        // 判断此属性是否有Setter                          if (!p.CanWrite) continue;//该属性不可写,直接跳出                          object value = row[tempName];                        p.SetValue(t, StrHelper.ConvertType(value, p.PropertyType), null);                    }                }                ts[i] = t;                i++;            }            return ts;        }    }}

posted @ 2020-05-20 09:56  咖啡无眠  阅读(619)  评论(0编辑  收藏  举报