EF 查询扩展

using Microsoft.EntityFrameworkCore;
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.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;

namespace Holder.ERP.System.Services
{
    /// <summary>
    /// EF扩展
    /// </summary>
    public static class EFExtension
    {/// <summary>
        /// 返回查询的数据
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="context">数据上下文</param>
        /// <param name="sql">sql语句</param>
        /// <param name="parameters">slq参数</param>
        /// <returns></returns>
        public static async Task<IEnumerable<T>> ExecuteReaderAsync<T>(this DbContext context, RawSqlString sql, params object[] parameters) where T : new()
        {
            var relationalDataReader = await ExecuteReaderAsync(context.Database, sql, parameters.ToArray());
            var reader = relationalDataReader.DbDataReader;
            var properties = typeof(T).GetProperties();
            var result = new List<T>();
            while (reader.Read())
            {
                var row = new Dictionary<string, object>();
                for (var fieldCount = 0; fieldCount < reader.FieldCount; fieldCount++)
                {
                    row.Add(reader.GetName(fieldCount), reader[fieldCount]);
                }
                var data = new T();
                foreach (var prop in properties)
                {
                    if (row.TryGetValue(prop.Name, out object value))
                    {
                        prop.SetValue(data, value == DBNull.Value ? null : value);
                    }
                }
                result.Add(data);
            }
            reader.Close();
            return result;
        }

        public static async Task<RelationalDataReader> ExecuteReaderAsync(
            this DatabaseFacade databaseFacade,
            RawSqlString sql,
            IEnumerable<object> parameters,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            using (await databaseFacade.GetService<IConcurrencyDetector>().EnterCriticalSectionAsync(cancellationToken))
            {
                RawSqlCommand rawSqlCommand = databaseFacade.GetRelationalService<IRawSqlCommandBuilder>().Build(sql.Format, parameters);
                return await rawSqlCommand.RelationalCommand.ExecuteReaderAsync(databaseFacade.GetRelationalService<IRelationalConnection>(), rawSqlCommand.ParameterValues, cancellationToken);
            }
        }

        private static TService GetRelationalService<TService>(
            this IInfrastructure<IServiceProvider> databaseFacade)
        {
            TService service = databaseFacade.Instance.GetService<TService>();
            if (service != null)
                return service;
            throw new InvalidOperationException(RelationalStrings.RelationalNotInUse);
        }
    }
}

 

posted @ 2019-10-23 17:07  刘小吉  阅读(546)  评论(1编辑  收藏  举报