添加项目文件。

This commit is contained in:
DK
2022-03-28 15:27:40 +08:00
parent b620fcb0cf
commit dc78fd1a09
898 changed files with 173053 additions and 0 deletions
@@ -0,0 +1,22 @@
using Newtonsoft.Json;
using System;
namespace IRaCIS.Core.Infrastructure.Extention
{
public static class CloneExtension
{
public static T Clone<T>(this T source)
{
// Don't serialize a null object, simply return the default for that object
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace };
var serializeSettings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source, serializeSettings), deserializeSettings);
}
}
}
@@ -0,0 +1,360 @@
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Text;
namespace IRaCIS.Core.Infrastructure.Extention
{
public static class ConvertJsonExtension
{
#region
/// <summary>
/// 过滤特殊字符
/// </summary>
/// <param name="s">字符串</param>
/// <returns>json字符串</returns>
private static string String2Json(String s)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.Length; i++)
{
char c = s.ToCharArray()[i];
switch (c)
{
case '\"':
sb.Append("\\\""); break;
case '\\':
sb.Append("\\\\"); break;
case '/':
sb.Append("\\/"); break;
case '\b':
sb.Append("\\b"); break;
case '\f':
sb.Append("\\f"); break;
case '\n':
sb.Append("\\n"); break;
case '\r':
sb.Append("\\r"); break;
case '\t':
sb.Append("\\t"); break;
default:
sb.Append(c); break;
}
}
return sb.ToString();
}
/// <summary>
/// 格式化字符型、日期型、布尔型
/// </summary>
/// <param name="str"></param>
/// <param name="type"></param>
/// <returns></returns>
private static string StringFormat(string str, Type type)
{
if (type == typeof(string))
{
str = String2Json(str);
str = "\"" + str + "\"";
}
else if (type == typeof(DateTime))
{
str = "\"" + str + "\"";
}
else if (type == typeof(bool))
{
str = str.ToLower();
}
else if (type != typeof(string) && string.IsNullOrEmpty(str))
{
str = "\"" + str + "\"";
}
return str;
}
#endregion
#region list转换成JSON
/// <summary>
/// list转换为Json
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <returns></returns>
public static string ListToJson<T>(this IList<T> list)
{
object obj = list[0];
return ListToJson<T>(list, obj.GetType().Name);
}
/// <summary>
/// list转换为json
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <param name="list"></param>
/// <param name="p"></param>
/// <returns></returns>
private static string ListToJson<T>(this IList<T> list, string JsonName)
{
if (list.Count == 0)
{
return "";
}
StringBuilder Json = new StringBuilder();
if (string.IsNullOrEmpty(JsonName))
JsonName = list[0].GetType().Name;
Json.Append("{\"" + JsonName + "\":[");
for (int i = 0; i < list.Count; i++)
{
T obj = Activator.CreateInstance<T>();
PropertyInfo[] pi = obj.GetType().GetProperties();
Json.Append("{");
for (int j = 0; j < pi.Length; j++)
{
Type type = pi[j].GetValue(list[i], null).GetType();
Json.Append("\"" + pi[j].Name.ToString() + "\":" + StringFormat(pi[j].GetValue(list[i], null).ToString(), type));
if (j < pi.Length - 1)
{
Json.Append(",");
}
}
Json.Append("}");
if (i < list.Count - 1)
{
Json.Append(",");
}
}
Json.Append("]}");
return Json.ToString();
}
#endregion
#region Json
/// <summary>
/// 对象转换为json
/// </summary>
/// <param name="jsonObject">json对象</param>
/// <returns>json字符串</returns>
public static string ToJson(this object jsonObject)
{
string jsonString = "{";
PropertyInfo[] propertyInfo = jsonObject.GetType().GetProperties();
for (int i = 0; i < propertyInfo.Length; i++)
{
object objectValue = propertyInfo[i].GetGetMethod().Invoke(jsonObject, null);
string value = string.Empty;
if (objectValue is DateTime || objectValue is Guid || objectValue is TimeSpan)
{
value = "'" + objectValue.ToString() + "'";
}
else if (objectValue is string)
{
value = "'" + ToJson(objectValue.ToString()) + "'";
}
else if (objectValue is IEnumerable)
{
value = ToJson((IEnumerable)objectValue);
}
else
{
value = ToJson(objectValue.ToString());
}
jsonString += "\"" + ToJson(propertyInfo[i].Name) + "\":" + value + ",";
}
jsonString.Remove(jsonString.Length - 1, jsonString.Length);
return jsonString + "}";
}
#endregion
#region json
/// <summary>
/// 对象集合转换为json
/// </summary>
/// <param name="array">对象集合</param>
/// <returns>json字符串</returns>
public static string ToJson(this IEnumerable array)
{
string jsonString = "{";
foreach (object item in array)
{
jsonString += ToJson(item) + ",";
}
jsonString.Remove(jsonString.Length - 1, jsonString.Length);
return jsonString + "]";
}
#endregion
#region Json
/// <summary>
/// 普通集合转换Json
/// </summary>
/// <param name="array">集合对象</param>
/// <returns>Json字符串</returns>
public static string ToArrayString(this IEnumerable array)
{
string jsonString = "[";
foreach (object item in array)
{
jsonString = ToJson(item.ToString()) + ",";
}
jsonString.Remove(jsonString.Length - 1, jsonString.Length);
return jsonString + "]";
}
#endregion
#region DataSet转换为Json
/// <summary>
/// DataSet转换为Json
/// </summary>
/// <param name="dataSet">DataSet对象</param>
/// <returns>Json字符串</returns>
public static string ToJson(this DataSet dataSet)
{
string jsonString = "{";
foreach (DataTable table in dataSet.Tables)
{
jsonString += "\"" + table.TableName + "\":" + ToJson(table) + ",";
}
jsonString = jsonString.TrimEnd(',');
return jsonString + "}";
}
#endregion
#region Datatable转换为Json
/// <summary>
/// Datatable转换为Json
/// </summary>
/// <param name="table">Datatable对象</param>
/// <returns>Json字符串</returns>
public static string ToJson(this DataTable dt)
{
StringBuilder jsonString = new StringBuilder();
jsonString.Append("[");
DataRowCollection drc = dt.Rows;
for (int i = 0; i < drc.Count; i++)
{
jsonString.Append("{");
for (int j = 0; j < dt.Columns.Count; j++)
{
string strKey = dt.Columns[j].ColumnName;
string strValue = drc[i][j].ToString();
Type type = dt.Columns[j].DataType;
jsonString.Append("\"" + strKey + "\":");
strValue = StringFormat(strValue, type);
if (j < dt.Columns.Count - 1)
{
jsonString.Append(strValue + ",");
}
else
{
jsonString.Append(strValue);
}
}
jsonString.Append("},");
}
jsonString.Remove(jsonString.Length - 1, 1);
jsonString.Append("]");
return jsonString.ToString();
}
/// <summary>
/// DataTable转换为Json
/// </summary>
public static string ToJson(this DataTable dt, string jsonName)
{
StringBuilder Json = new StringBuilder();
if (string.IsNullOrEmpty(jsonName))
jsonName = dt.TableName;
Json.Append("{\"" + jsonName + "\":[");
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
Json.Append("{");
for (int j = 0; j < dt.Columns.Count; j++)
{
Type type = dt.Rows[i][j].GetType();
Json.Append("\"" + dt.Columns[j].ColumnName.ToString() + "\":" + StringFormat(dt.Rows[i][j].ToString(), type));
if (j < dt.Columns.Count - 1)
{
Json.Append(",");
}
}
Json.Append("}");
if (i < dt.Rows.Count - 1)
{
Json.Append(",");
}
}
}
Json.Append("]}");
return Json.ToString();
}
#endregion
#region DataReader转换为Json
/// <summary>
/// DataReader转换为Json
/// </summary>
/// <param name="dataReader">DataReader对象</param>
/// <returns>Json字符串</returns>
public static string ReaderJson(this IDataReader dataReader)
{
StringBuilder jsonString = new StringBuilder();
Dictionary<string, Type> ModelField = new Dictionary<string, Type>();
for (int i = 0; i < dataReader.FieldCount; i++)
{
ModelField.Add(dataReader.GetName(i), dataReader.GetFieldType(i));
}
jsonString.Append("[");
while (dataReader.Read())
{
jsonString.Append("{");
foreach (KeyValuePair<string, Type> keyVal in ModelField)
{
Type type = keyVal.Value;
string strKey = keyVal.Key;
string strValue = dataReader[strKey].ToString();
jsonString.Append("\"" + strKey + "\":");
strValue = StringFormat(strValue, type);
jsonString.Append(strValue + ",");
}
jsonString.Remove(jsonString.Length - 1, 1);
jsonString.Append("},");
}
dataReader.Close();
jsonString.Remove(jsonString.Length - 1, 1);
jsonString.Append("]");
return jsonString.ToString();
}
#endregion
public static T DeserializeObject<T>(this string entityString)
{
if (string.IsNullOrEmpty(entityString))
{
return default(T);
}
if (entityString == "{}")
{
entityString = "[]";
}
return JsonConvert.DeserializeObject<T>(entityString);
}
public static string Serialize(this object obj, JsonSerializerSettings formatDate = null)
{
if (obj == null) return null;
formatDate = formatDate ?? new JsonSerializerSettings
{
DateFormatString = "yyyy-MM-dd HH:mm:ss"
};
return JsonConvert.SerializeObject(obj, formatDate);
}
}
}
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace IRaCIS.Core.Infrastructure.Extention
{
public static class EnumToSelectExtension
{
/// <summary>
/// 将枚举转换成字典(枚举,自定义描述)
/// </summary>
/// <typeparam name="TEnum"></typeparam>
/// <param name="exceptList">需要排除的枚举</param>
/// <returns></returns>
public static Dictionary<object, string> ToSelect<TEnum>( params TEnum[] exceptList) where TEnum : struct, Enum
{
var type = typeof(TEnum);
var dict = new Dictionary<object, string>();
foreach (var value in Enum.GetValues<TEnum>())
//foreach (var value in type.GetEnumValues())
{
var attr = type.GetField(value.ToString())
.GetCustomAttribute<DescriptionAttribute>();
if (attr is null || exceptList.Contains(value)) continue;
var key = type.GetFields().FirstOrDefault(t=>t.Name== value.ToString()).GetRawConstantValue();
dict[key] = attr.Description;
}
return dict;
}
}
}
@@ -0,0 +1,63 @@
using System.IO;
using System.Threading.Tasks;
namespace IRaCIS.Core.Infrastructure.Extention
{
/// <summary>
/// 大文件操作扩展类
/// </summary>
public static class FileExt
{
/// <summary>
/// 以文件流的形式复制大文件
/// </summary>
/// <param name="fs">源</param>
/// <param name="dest">目标地址</param>
/// <param name="bufferSize">缓冲区大小,默认8MB</param>
public static void CopyToFile(this Stream fs, string dest, int bufferSize = 1024 * 8 * 1024)
{
using var fsWrite = new FileStream(dest, FileMode.OpenOrCreate, FileAccess.ReadWrite);
byte[] buf = new byte[bufferSize];
int len;
while ((len = fs.Read(buf, 0, buf.Length)) != 0)
{
fsWrite.Write(buf, 0, len);
}
}
/// <summary>
/// 以文件流的形式复制大文件(异步方式)
/// </summary>
/// <param name="fs">源</param>
/// <param name="dest">目标地址</param>
/// <param name="bufferSize">缓冲区大小,默认8MB</param>
public static async void CopyToFileAsync(this Stream fs, string dest, int bufferSize = 1024 * 1024 * 8)
{
using var fsWrite = new FileStream(dest, FileMode.OpenOrCreate, FileAccess.ReadWrite);
byte[] buf = new byte[bufferSize];
int len;
await Task.Run(() =>
{
while ((len = fs.Read(buf, 0, buf.Length)) != 0)
{
fsWrite.Write(buf, 0, len);
}
}).ConfigureAwait(true);
}
/// <summary>
/// 将内存流转储成文件
/// </summary>
/// <param name="ms"></param>
/// <param name="filename"></param>
public static void SaveFile(this MemoryStream ms, string filename)
{
using var fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
byte[] buffer = ms.ToArray(); // 转化为byte格式存储
fs.Write(buffer, 0, buffer.Length);
fs.Flush();
}
}
}
@@ -0,0 +1,437 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace IRaCIS.Core.Infrastructure.Extention
{
public static class IDictionaryExtensions
{
/// <summary>
/// 添加或更新键值对
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="that">另一个字典集</param>
/// <returns></returns>
public static void AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that)
{
foreach (var item in that)
{
@this[item.Key] = item.Value;
}
}
/// <summary>
/// 添加或更新键值对
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="that">另一个字典集</param>
/// <returns></returns>
public static void AddOrUpdateTo<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that)
{
foreach (var item in @this)
{
that[item.Key] = item.Value;
}
}
/// <summary>
/// 添加或更新键值对
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="key">键</param>
/// <param name="addValue">添加时的值</param>
/// <param name="updateValueFactory">更新时的操作</param>
/// <returns></returns>
public static TValue AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory)
{
if (!@this.ContainsKey(key))
{
@this.Add(key, addValue);
}
else
{
@this[key] = updateValueFactory(key, @this[key]);
}
return @this[key];
}
/// <summary>
/// 添加或更新键值对
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="key">键</param>
/// <param name="addValue">添加时的值</param>
/// <param name="updateValueFactory">更新时的操作</param>
/// <returns></returns>
public static async Task<TValue> AddOrUpdateAsync<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, TValue addValue, Func<TKey, TValue, Task<TValue>> updateValueFactory)
{
if (!@this.ContainsKey(key))
{
@this.Add(key, addValue);
}
else
{
@this[key] = await updateValueFactory(key, @this[key]);
}
return @this[key];
}
/// <summary>
/// 添加或更新键值对
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="key">键</param>
/// <param name="addValue">添加时的值</param>
/// <param name="updateValue">更新时的值</param>
/// <returns></returns>
public static TValue AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, TValue addValue, TValue updateValue)
{
if (!@this.ContainsKey(key))
{
@this.Add(key, addValue);
}
else
{
@this[key] = updateValue;
}
return @this[key];
}
/// <summary>
/// 添加或更新键值对
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="that">另一个字典集</param>
/// <param name="updateValueFactory">更新时的操作</param>
/// <returns></returns>
public static void AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that, Func<TKey, TValue, TValue> updateValueFactory)
{
foreach (var item in that)
{
AddOrUpdate(@this, item.Key, item.Value, updateValueFactory);
}
}
/// <summary>
/// 添加或更新键值对
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="that">另一个字典集</param>
/// <param name="updateValueFactory">更新时的操作</param>
/// <returns></returns>
public static Task AddOrUpdateAsync<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that, Func<TKey, TValue, Task<TValue>> updateValueFactory)
{
return that.ForeachAsync(item => AddOrUpdateAsync(@this, item.Key, item.Value, updateValueFactory));
}
/// <summary>
/// 添加或更新键值对
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="that">另一个字典集</param>
/// <param name="updateValueFactory">更新时的操作</param>
/// <returns></returns>
public static void AddOrUpdateTo<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that, Func<TKey, TValue, TValue> updateValueFactory)
{
foreach (var item in @this)
{
AddOrUpdate(that, item.Key, item.Value, updateValueFactory);
}
}
/// <summary>
/// 添加或更新键值对
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="that">另一个字典集</param>
/// <param name="updateValueFactory">更新时的操作</param>
/// <returns></returns>
public static Task AddOrUpdateAsyncTo<TKey, TValue>(this IDictionary<TKey, TValue> @this, IDictionary<TKey, TValue> that, Func<TKey, TValue, Task<TValue>> updateValueFactory)
{
return @this.ForeachAsync(item => AddOrUpdateAsync(that, item.Key, item.Value, updateValueFactory));
}
/// <summary>
/// 添加或更新键值对
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="key">键</param>
/// <param name="addValueFactory">添加时的操作</param>
/// <param name="updateValueFactory">更新时的操作</param>
/// <returns></returns>
public static TValue AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
{
if (!@this.ContainsKey(key))
{
@this.Add(key, addValueFactory(key));
}
else
{
@this[key] = updateValueFactory(key, @this[key]);
}
return @this[key];
}
/// <summary>
/// 添加或更新键值对
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="key">键</param>
/// <param name="addValueFactory">添加时的操作</param>
/// <param name="updateValueFactory">更新时的操作</param>
/// <returns></returns>
public static async Task<TValue> AddOrUpdateAsync<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, Func<TKey, Task<TValue>> addValueFactory, Func<TKey, TValue, Task<TValue>> updateValueFactory)
{
if (!@this.ContainsKey(key))
{
@this.Add(key, await addValueFactory(key));
}
else
{
@this[key] = await updateValueFactory(key, @this[key]);
}
return @this[key];
}
/// <summary>
/// 获取或添加
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="key"></param>
/// <param name="addValueFactory"></param>
/// <returns></returns>
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, Func<TValue> addValueFactory)
{
if (!@this.ContainsKey(key))
{
@this.Add(key, addValueFactory());
}
return @this[key];
}
/// <summary>
/// 获取或添加
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="key"></param>
/// <param name="addValueFactory"></param>
/// <returns></returns>
public static async Task<TValue> GetOrAddAsync<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, Func<Task<TValue>> addValueFactory)
{
if (!@this.ContainsKey(key))
{
@this.Add(key, await addValueFactory());
}
return @this[key];
}
/// <summary>
/// 获取或添加
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="this"></param>
/// <param name="key"></param>
/// <param name="addValue"></param>
/// <returns></returns>
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> @this, TKey key, TValue addValue)
{
if (!@this.ContainsKey(key))
{
@this.Add(key, addValue);
}
return @this[key];
}
/// <summary>
/// 遍历IEnumerable
/// </summary>
/// <param name="dic"></param>
/// <param name="action">回调方法</param>
public static void ForEach<TKey, TValue>(this IDictionary<TKey, TValue> dic, Action<TKey, TValue> action)
{
foreach (var item in dic)
{
action(item.Key, item.Value);
}
}
/// <summary>
/// 遍历IDictionary
/// </summary>
/// <param name="dic"></param>
/// <param name="action">回调方法</param>
public static Task ForEachAsync<TKey, TValue>(this IDictionary<TKey, TValue> dic, Func<TKey, TValue, Task> action)
{
return dic.ForeachAsync(x => action(x.Key, x.Value));
}
/// <summary>
/// 安全的转换成字典集
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <param name="source"></param>
/// <param name="keySelector">键选择器</param>
/// <returns></returns>
public static Dictionary<TKey, TSource> ToDictionarySafety<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var dic = new Dictionary<TKey, TSource>();
foreach (var item in source)
{
dic[keySelector(item)] = item;
}
return dic;
}
/// <summary>
/// 安全的转换成字典集
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TElement"></typeparam>
/// <param name="source"></param>
/// <param name="keySelector">键选择器</param>
/// <param name="elementSelector">值选择器</param>
/// <returns></returns>
public static Dictionary<TKey, TElement> ToDictionarySafety<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
{
var dic = new Dictionary<TKey, TElement>();
foreach (var item in source)
{
dic[keySelector(item)] = elementSelector(item);
}
return dic;
}
/// <summary>
/// 安全的转换成字典集
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TElement"></typeparam>
/// <param name="source"></param>
/// <param name="keySelector">键选择器</param>
/// <param name="elementSelector">值选择器</param>
/// <returns></returns>
public static async Task<IDictionary<TKey, TElement>> ToDictionarySafetyAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector)
{
var dic = new ConcurrentDictionary<TKey, TElement>();
await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item));
return dic;
}
/// <summary>
/// 安全的转换成字典集
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TElement"></typeparam>
/// <param name="source"></param>
/// <param name="keySelector">键选择器</param>
/// <returns></returns>
public static ConcurrentDictionary<TKey, TSource> ToConcurrentDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var dic = new ConcurrentDictionary<TKey, TSource>();
foreach (var item in source)
{
dic[keySelector(item)] = item;
}
return dic;
}
/// <summary>
/// 安全的转换成字典集
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TElement"></typeparam>
/// <param name="source"></param>
/// <param name="keySelector">键选择器</param>
/// <param name="elementSelector">值选择器</param>
/// <returns></returns>
public static ConcurrentDictionary<TKey, TElement> ToConcurrentDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
{
var dic = new ConcurrentDictionary<TKey, TElement>();
foreach (var item in source)
{
dic[keySelector(item)] = elementSelector(item);
}
return dic;
}
/// <summary>
/// 安全的转换成字典集
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TElement"></typeparam>
/// <param name="source"></param>
/// <param name="keySelector">键选择器</param>
/// <param name="elementSelector">值选择器</param>
/// <returns></returns>
public static async Task<ConcurrentDictionary<TKey, TElement>> ToConcurrentDictionaryAsync<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, Task<TElement>> elementSelector)
{
var dic = new ConcurrentDictionary<TKey, TElement>();
await source.ForeachAsync(async item => dic[keySelector(item)] = await elementSelector(item));
return dic;
}
/// <summary>
/// 转换成并发字典集合
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="dic"></param>
/// <returns></returns>
public static ConcurrentDictionary<TKey, TValue> AsConcurrentDictionary<TKey, TValue>(this Dictionary<TKey, TValue> dic) => new(dic);
/// <summary>
/// 转换成普通字典集合
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="dic"></param>
/// <returns></returns>
public static Dictionary<TKey, TValue> AsDictionary<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dic) => new(dic);
}
}
@@ -0,0 +1,600 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace IRaCIS.Core.Infrastructure.Extention
{
public static partial class IEnumerableExtensions
{
/// <summary>
/// 按字段去重
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <param name="source"></param>
/// <param name="keySelector"></param>
/// <returns></returns>
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var hash = new HashSet<TKey>();
return source.Where(p => hash.Add(keySelector(p)));
}
/// <summary>
/// 添加多个元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="this"></param>
/// <param name="values"></param>
public static void AddRange<T>(this ICollection<T> @this, params T[] values)
{
foreach (var obj in values)
{
@this.Add(obj);
}
}
/// <summary>
/// 添加符合条件的多个元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="this"></param>
/// <param name="predicate"></param>
/// <param name="values"></param>
public static void AddRangeIf<T>(this ICollection<T> @this, Func<T, bool> predicate, params T[] values)
{
foreach (var obj in values)
{
if (predicate(obj))
{
@this.Add(obj);
}
}
}
/// <summary>
/// 添加不重复的元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="this"></param>
/// <param name="values"></param>
public static void AddRangeIfNotContains<T>(this ICollection<T> @this, params T[] values)
{
foreach (T obj in values)
{
if (!@this.Contains(obj))
{
@this.Add(obj);
}
}
}
/// <summary>
/// 移除符合条件的元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="this"></param>
/// <param name="where"></param>
public static void RemoveWhere<T>(this ICollection<T> @this, Func<T, bool> @where)
{
foreach (var obj in @this.Where(where).ToList())
{
@this.Remove(obj);
}
}
/// <summary>
/// 在元素之后添加元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="condition">条件</param>
/// <param name="value">值</param>
public static void InsertAfter<T>(this IList<T> list, Func<T, bool> condition, T value)
{
foreach (var item in list.Select((item, index) => new { item, index }).Where(p => condition(p.item)).OrderByDescending(p => p.index))
{
if (item.index + 1 == list.Count)
{
list.Add(value);
}
else
{
list.Insert(item.index + 1, value);
}
}
}
/// <summary>
/// 在元素之后添加元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="index">索引位置</param>
/// <param name="value">值</param>
public static void InsertAfter<T>(this IList<T> list, int index, T value)
{
foreach (var item in list.Select((v, i) => new { Value = v, Index = i }).Where(p => p.Index == index).OrderByDescending(p => p.Index))
{
if (item.Index + 1 == list.Count)
{
list.Add(value);
}
else
{
list.Insert(item.Index + 1, value);
}
}
}
/// <summary>
/// 转HashSet
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static HashSet<TResult> ToHashSet<T, TResult>(this IEnumerable<T> source, Func<T, TResult> selector)
{
var set = new HashSet<TResult>();
set.UnionWith(source.Select(selector));
return set;
}
/// <summary>
/// 遍历IEnumerable
/// </summary>
/// <param name="objs"></param>
/// <param name="action">回调方法</param>
/// <typeparam name="T"></typeparam>
public static void ForEach<T>(this IEnumerable<T> objs, Action<T> action)
{
foreach (var o in objs)
{
action(o);
}
}
/// <summary>
/// 异步foreach
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="maxParallelCount">最大并行数</param>
/// <param name="action"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task ForeachAsync<T>(this IEnumerable<T> source, Func<T, Task> action, int maxParallelCount, CancellationToken cancellationToken = default)
{
var list = new List<Task>();
foreach (var item in source)
{
if (cancellationToken.IsCancellationRequested)
{
return;
}
list.Add(action(item));
if (list.Count >= maxParallelCount)
{
await Task.WhenAll(list);
list.Clear();
}
}
await Task.WhenAll(list);
}
/// <summary>
/// 异步foreach
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action"></param>
/// <returns></returns>
public static Task ForeachAsync<T>(this IEnumerable<T> source, Func<T, Task> action, CancellationToken cancellationToken = default)
{
return ForeachAsync(source, action, source.Count(), cancellationToken);
}
/// <summary>
/// 异步Select
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static Task<TResult[]> SelectAsync<T, TResult>(this IEnumerable<T> source, Func<T, Task<TResult>> selector)
{
return Task.WhenAll(source.Select(selector));
}
/// <summary>
/// 异步Select
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static Task<TResult[]> SelectAsync<T, TResult>(this IEnumerable<T> source, Func<T, int, Task<TResult>> selector)
{
return Task.WhenAll(source.Select(selector));
}
/// <summary>
/// 异步For
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <param name="maxParallelCount">最大并行数</param>
/// <param name="cancellationToken">取消口令</param>
/// <returns></returns>
public static async Task ForAsync<T>(this IEnumerable<T> source, Func<T, int, Task> selector, int maxParallelCount, CancellationToken cancellationToken = default)
{
var list = new List<Task>();
int index = 0;
foreach (var item in source)
{
if (cancellationToken.IsCancellationRequested)
{
return;
}
list.Add(selector(item, index++));
if (list.Count >= maxParallelCount)
{
await Task.WhenAll(list);
list.Clear();
}
}
await Task.WhenAll(list);
}
/// <summary>
/// 异步For
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <param name="cancellationToken">取消口令</param>
/// <returns></returns>
public static Task ForAsync<T>(this IEnumerable<T> source, Func<T, int, Task> selector, CancellationToken cancellationToken = default)
{
return ForAsync(source, selector, source.Count(), cancellationToken);
}
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static TResult MaxOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector)
=> source.Select(selector).DefaultIfEmpty().Max();
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TResult MaxOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector, TResult defaultValue) => source.Select(selector).DefaultIfEmpty(defaultValue).Max();
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static TSource MaxOrDefault<TSource>(this IQueryable<TSource> source) => source.DefaultIfEmpty().Max();
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TSource MaxOrDefault<TSource>(this IQueryable<TSource> source, TSource defaultValue) => source.DefaultIfEmpty(defaultValue).Max();
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TResult MaxOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector, TResult defaultValue) => source.Select(selector).DefaultIfEmpty(defaultValue).Max();
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static TResult MaxOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) => source.Select(selector).DefaultIfEmpty().Max();
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static TSource MaxOrDefault<TSource>(this IEnumerable<TSource> source) => source.DefaultIfEmpty().Max();
/// <summary>
/// 取最大值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TSource MaxOrDefault<TSource>(this IEnumerable<TSource> source, TSource defaultValue) => source.DefaultIfEmpty(defaultValue).Max();
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static TResult MinOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector) => source.Select(selector).DefaultIfEmpty().Min();
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TResult MinOrDefault<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector, TResult defaultValue) => source.Select(selector).DefaultIfEmpty(defaultValue).Min();
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static TSource MinOrDefault<TSource>(this IQueryable<TSource> source) => source.DefaultIfEmpty().Min();
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TSource MinOrDefault<TSource>(this IQueryable<TSource> source, TSource defaultValue) => source.DefaultIfEmpty(defaultValue).Min();
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static TResult MinOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) => source.Select(selector).DefaultIfEmpty().Min();
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TResult MinOrDefault<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector, TResult defaultValue) => source.Select(selector).DefaultIfEmpty(defaultValue).Min();
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static TSource MinOrDefault<TSource>(this IEnumerable<TSource> source) => source.DefaultIfEmpty().Min();
/// <summary>
/// 取最小值
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="source"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TSource MinOrDefault<TSource>(this IEnumerable<TSource> source, TSource defaultValue) => source.DefaultIfEmpty(defaultValue).Min();
///// <summary>
///// 标准差
///// </summary>
///// <typeparam name="T"></typeparam>
///// <param name="source"></param>
///// <param name="selector"></param>
///// <returns></returns>
//public static TResult StandardDeviation<T, TResult>(this IEnumerable<T> source, Func<T, TResult> selector) where TResult : IConvertible
//{
// return StandardDeviation(source.Select(t => selector(t).ConvertTo<double>())).ConvertTo<TResult>();
//}
///// <summary>
///// 标准差
///// </summary>
///// <typeparam name="T"></typeparam>
///// <param name="source"></param>
///// <returns></returns>
//public static T StandardDeviation<T>(this IEnumerable<T> source) where T : IConvertible
//{
// return StandardDeviation(source.Select(t => t.ConvertTo<double>())).ConvertTo<T>();
//}
/// <summary>
/// 标准差
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static double StandardDeviation(this IEnumerable<double> source)
{
double result = 0;
int count = source.Count();
if (count > 1)
{
double avg = source.Average();
double sum = source.Sum(d => (d - avg) * (d - avg));
result = Math.Sqrt(sum / count);
}
return result;
}
/// <summary>
/// 随机排序
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static IOrderedEnumerable<T> OrderByRandom<T>(this IEnumerable<T> source)
{
return source.OrderBy(_ => Guid.NewGuid());
}
/// <summary>
/// 序列相等
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="first"></param>
/// <param name="second"></param>
/// <param name="condition"></param>
/// <returns></returns>
public static bool SequenceEqual<T>(this IEnumerable<T> first, IEnumerable<T> second, Func<T, T, bool> condition)
{
if (first is ICollection<T> source1 && second is ICollection<T> source2)
{
if (source1.Count != source2.Count)
{
return false;
}
if (source1 is IList<T> list1 && source2 is IList<T> list2)
{
int count = source1.Count;
for (int index = 0; index < count; ++index)
{
if (!condition(list1[index], list2[index]))
{
return false;
}
}
return true;
}
}
using IEnumerator<T> enumerator1 = first.GetEnumerator();
using IEnumerator<T> enumerator2 = second.GetEnumerator();
while (enumerator1.MoveNext())
{
if (!enumerator2.MoveNext() || !condition(enumerator1.Current, enumerator2.Current))
{
return false;
}
}
return !enumerator2.MoveNext();
}
/// <summary>
/// 序列相等
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <typeparam name="T2"></typeparam>
/// <param name="first"></param>
/// <param name="second"></param>
/// <param name="condition"></param>
/// <returns></returns>
public static bool SequenceEqual<T1, T2>(this IEnumerable<T1> first, IEnumerable<T2> second, Func<T1, T2, bool> condition)
{
if (first is ICollection<T1> source1 && second is ICollection<T2> source2)
{
if (source1.Count != source2.Count)
{
return false;
}
if (source1 is IList<T1> list1 && source2 is IList<T2> list2)
{
int count = source1.Count;
for (int index = 0; index < count; ++index)
{
if (!condition(list1[index], list2[index]))
{
return false;
}
}
return true;
}
}
using IEnumerator<T1> enumerator1 = first.GetEnumerator();
using IEnumerator<T2> enumerator2 = second.GetEnumerator();
while (enumerator1.MoveNext())
{
if (!enumerator2.MoveNext() || !condition(enumerator1.Current, enumerator2.Current))
{
return false;
}
}
return !enumerator2.MoveNext();
}
/// <summary>
/// 对比两个集合哪些是新增的、删除的、修改的
/// </summary>
/// <typeparam name="T1"></typeparam>
/// <typeparam name="T2"></typeparam>
/// <param name="olds"></param>
/// <param name="news"></param>
/// <param name="key1Selector">对比因素属性</param>
/// <param name="key2Selector">对比因素属性</param>
/// <returns></returns>
public static (List<T2> adds, List<T1> remove, List<T1> updates) CompareChanges<T1, T2>(this IEnumerable<T1> olds, IEnumerable<T2> news, Func<T1, object> key1Selector, Func<T2, object> key2Selector)
{
return (news.Where(c => olds.All(m => key1Selector(m) != key2Selector(c))).ToList(), olds.Where(m => news.All(c => key2Selector(c) != key1Selector(m))).ToList(), olds.Where(m => news.Any(c => key1Selector(m) == key2Selector(c))).ToList());
}
/// <summary>
/// 对比两个集合哪些是新增的、删除的、修改的
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="olds"></param>
/// <param name="news"></param>
/// <param name="keySelector">对比因素属性</param>
/// <returns></returns>
public static (List<T> adds, List<T> remove, List<T> updates) CompareChanges<T>(this IEnumerable<T> olds, IEnumerable<T> news, Func<T, object> keySelector)
{
return (news.Where(c => olds.All(m => keySelector(m) != keySelector(c))).ToList(), olds.Where(m => news.All(c => keySelector(c) != keySelector(m))).ToList(), olds.Where(m => news.Any(c => keySelector(m) == keySelector(c))).ToList());
}
}
}
@@ -0,0 +1,184 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
namespace IRaCIS.Core.Infrastructure.Extention
{
public static class QueryablePageListExtensions
{
//单字段排序
public static PageOutput<T> ToPagedList<T>(this IQueryable<T> source, int pageIndex, int pageSize, string defaultSortFiled = "Id", bool isAsc = true)
{
if (pageIndex <= 0)
{
pageIndex = 1;
}
if (pageSize <= 0)
{
pageSize = 10;
}
var count = source.Count();
if (count == 0)
{
return new PageOutput<T>() { CurrentPageData=new T[0] };
}
var propName = string.IsNullOrWhiteSpace(defaultSortFiled) ? "Id" : defaultSortFiled;
source = isAsc ? source.OrderBy(propName) : source.OrderBy(propName + " desc");
source = source.Skip((pageIndex - 1) * pageSize);
var items = source
.Take(pageSize)
.ToArray();
var pagedList = new PageOutput<T>()
{
PageIndex = pageIndex,
PageSize = pageSize,
TotalCount = count,
CurrentPageData = items
};
return pagedList;
}
//单字段排序 异步
public static async Task<PageOutput<T>> ToPagedListAsync<T>(this IQueryable<T> source, int pageNumber, int pageSize, string defaultSortFiled = "Id", bool isAsc = true,bool isMultiSortFiled=false, string[] sortArray=default, CancellationToken cancellationToken = default)
{
if (isMultiSortFiled&& sortArray==default)
{
throw new System.Exception("必须指定排序字段");
}
if (pageNumber <= 0)
{
pageNumber = 1;
}
if (pageSize <= 0)
{
pageSize = 10;
}
var count = await source.CountAsync(cancellationToken).ConfigureAwait(false);
if (count == 0)
{
return new PageOutput<T>() { CurrentPageData = new T[0] };
}
var propName = string.IsNullOrWhiteSpace(defaultSortFiled) ? "Id" : defaultSortFiled;
if (!isMultiSortFiled)
{
source = isAsc ? source.OrderBy(propName) : source.OrderBy(propName + " desc");
}
else
{
var sortString = string.Join(',', sortArray);
source= source.OrderBy(sortString);
}
source = source.Skip((pageNumber - 1) * pageSize);
var items = await source
.Take(pageSize)
.ToArrayAsync(cancellationToken)
.ConfigureAwait(false);
var pagedList = new PageOutput<T>()
{
PageIndex = pageNumber,
PageSize = pageSize,
TotalCount = count,
CurrentPageData = items
};
return pagedList;
}
//多字段排序 ["a asc", "b desc", "c asc"]
public static PageOutput<T> ToPagedList<T>(this IQueryable<T> source, int pageIndex, int pageSize,string[] sortArray)
{
if (pageIndex <= 0)
{
pageIndex = 1;
}
if (pageSize <= 0)
{
pageSize = 10;
}
var count = source.Count();
if (count == 0)
{
return new PageOutput<T>() { CurrentPageData = new T[0] };
}
var sortString = string.Join(',', sortArray);
source.OrderBy(sortString);
source = source.Skip((pageIndex - 1) * pageSize);
var items = source
.Take(pageSize)
.ToArray();
var pagedList = new PageOutput<T>()
{
PageIndex = pageIndex,
PageSize = pageSize,
TotalCount = count,
CurrentPageData = items
};
return pagedList;
}
//多字段排序异步 ["a asc", "b desc", "c asc"]
public static async Task<PageOutput<T>> ToPagedListAsync<T>(this IQueryable<T> source, int pageNumber, int pageSize, string[] sortArray, CancellationToken cancellationToken = default)
{
if (pageNumber <= 0)
{
pageNumber = 1;
}
if (pageSize <= 0)
{
pageSize = 10;
}
var count = await source.CountAsync(cancellationToken).ConfigureAwait(false);
if (count == 0)
{
return new PageOutput<T>() { CurrentPageData = new T[0] };
}
var sortString = string.Join(',', sortArray);
source = source.OrderBy(sortString);
source = source.Skip((pageNumber - 1) * pageSize);
var items = await source
.Take(pageSize)
.ToArrayAsync(cancellationToken)
.ConfigureAwait(false);
var pagedList = new PageOutput<T>()
{
PageIndex = pageNumber,
PageSize = pageSize,
TotalCount = count,
CurrentPageData = items
};
return pagedList;
}
}
}
@@ -0,0 +1,22 @@
using System.Linq;
using System.Linq.Expressions;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace IRaCIS.Core.Infrastructure.Extention
{
public static class QueryableWhereExtension
{
public static IQueryable<TEntity> WhereIf<TEntity>(this IQueryable<TEntity> query, [NotNullWhen(true)] bool condition, Expression<Func<TEntity, bool>> filter) where TEntity : class
{
return condition ? query.Where(filter) : query;
}
public static IEnumerable<TEntity> WhereIf<TEntity>(this IEnumerable<TEntity> query, bool condition, Func<TEntity, bool> filter) where TEntity : class
{
return condition ? query.Where(filter) : query;
}
}
}
@@ -0,0 +1,24 @@
using System.Collections.Generic;
namespace IRaCIS.Core.Infrastructure.Extention
{
/// <summary>
/// 分页信息输入
/// </summary>
public class PageInput
{
public int PageIndex { get; set; } = 1;
public int PageSize { set; get; } = 10;
public bool Asc { get; set; } = true;
public string SortField { get; set; } = "";
}
public class PageInputMultiSort
{
public int PageIndex { get; set; } = 1;
public int PageSize { set; get; } = 10;
//["a asc", "b desc", "c asc"]
public string[] SortArray { get; set; }
}
}
@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace IRaCIS.Core.Infrastructure.Extention
{
/// <summary>
/// LINQ扩展方法
/// </summary>
public static class LinqExtension
{
/// <summary>
/// 与连接
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="left">左条件</param>
/// <param name="right">右条件</param>
/// <returns>新表达式</returns>
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
{
return CombineLambdas(left, right, ExpressionType.AndAlso);
}
/// <summary>
/// 或连接
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="left">左条件</param>
/// <param name="right">右条件</param>
/// <returns>新表达式</returns>
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
{
return CombineLambdas(left, right, ExpressionType.OrElse);
}
private static Expression<Func<T, bool>> CombineLambdas<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right, ExpressionType expressionType)
{
var visitor = new SubstituteParameterVisitor
{
Sub =
{
[right.Parameters[0]] = left.Parameters[0]
}
};
Expression body = Expression.MakeBinary(expressionType, left.Body, visitor.Visit(right.Body));
return Expression.Lambda<Func<T, bool>>(body, left.Parameters[0]);
}
}
internal class SubstituteParameterVisitor : ExpressionVisitor
{
public Dictionary<Expression, Expression> Sub = new Dictionary<Expression, Expression>();
protected override Expression VisitParameter(ParameterExpression node)
{
return Sub.TryGetValue(node, out var newValue) ? newValue : node;
}
}
}
@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace IRaCIS.Core.Infrastructure.Extention
{
public static class ListExtensions
{
/// <summary>
/// 将列表转换为树形结构
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="list">数据</param>
/// <param name="rootWhere">根条件</param>
/// <param name="childsWhere">节点条件</param>
/// <param name="addChilds">添加子节点</param>
/// <param name="childEntity"></param>
/// <returns></returns>
public static List<T> ToTree<T,Tkey>(this List<T> list, Func<T, T, bool> rootWhere, Func<T, T, bool> childsWhere, Action<T, IEnumerable<T>> addChilds, Func<T, Tkey> orderSelector, T childEntity = default)
{
if (rootWhere is null)
{
throw new ArgumentNullException(nameof(rootWhere));
}
if (childsWhere is null)
{
throw new ArgumentNullException(nameof(childsWhere));
}
if (addChilds is null)
{
throw new ArgumentNullException(nameof(addChilds));
}
if (orderSelector is null)
{
throw new ArgumentNullException(nameof(orderSelector));
}
var treelist = new List<T>();
//空树
if (list == null || list.Count == 0)
{
return treelist;
}
if (!list.Any(e => rootWhere(childEntity, e)))
{
return treelist;
}
//树根
if (list.Any(e => rootWhere(childEntity, e)))
{
treelist.AddRange(list.Where(e => rootWhere(childEntity, e)).OrderBy(orderSelector));
}
//树叶 item 是根
foreach (var item in treelist)
{
if (list.Any(e => childsWhere(item, e)))
{
var nodedata = list.Where(e => childsWhere(item, e)).OrderBy(orderSelector).ToList();
foreach (var child in nodedata)
{
//添加子集
var data = list.ToTree(childsWhere, childsWhere, addChilds, orderSelector, child);
addChilds(child, data);
}
addChilds(item, nodedata);
}
}
return treelist;
}
}
}
@@ -0,0 +1,34 @@
namespace IRaCIS.Core.Infrastructure.Extention
{
/// <summary>
/// 此处是为了 后续代替 IsSuccess IsSuccess暂时还是保留,接下来的接口判断现在用Code 判断 不用IsSuccess就好了
/// </summary>
public enum ApiResponseCodeEnum
{
//正常的 相当于之前的 IsSuccess = true
OK = 0,
//Api 输入参数有问题 相当于之前的 IsSuccess = false
ApiInputError = 1,
//业务验证不通过 相当于之前的 IsSuccess = false
BusinessValidationFailed = 2,
//数据不存在
DataNotExist=3,
//程序异常 相当于之前的 IsSuccess = false
ProgramException = 4,
//需要提示 ,需要提示 从Result 取数据
NeedTips = 5
}
}
@@ -0,0 +1,42 @@
namespace IRaCIS.Core.Infrastructure.Extention
{
/// <summary>
/// 响应数据输出接口
/// </summary>
public interface IResponseOutput
{
/// <summary>
/// 是否成功
/// </summary>
bool IsSuccess { get; }
public ApiResponseCodeEnum Code { get; set; }
/// <summary>
/// 消息
/// </summary>
string ErrorMessage { get; }
}
/// <summary>
/// 响应数据输出泛型接口
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IResponseOutput<T> : IResponseOutput
{
/// <summary>
/// 返回数据
/// </summary>
T Data { get; }
}
public interface IResponseOutput<T,T2> : IResponseOutput
{
/// <summary>
/// 返回数据
/// </summary>
T Data { get; }
T2 OtherInfo { get; }
}
}
@@ -0,0 +1,71 @@
using System;
using System.Diagnostics.CodeAnalysis;
namespace IRaCIS.Core.Infrastructure.Extention
{
public static class NUllCheckExtension
{
[DoesNotReturn]
public static TEntity IfNullThrowException<TEntity>(this TEntity businessObject) where TEntity : class
{
if(businessObject == null)
{
throw new QueryBusinessObjectNotExistException($"The query object {typeof(TEntity).Name} does not exist , or was deleted by someone else, or an incorrect parameter query caused");
}
else
{
return businessObject!;
}
}
[DoesNotReturn]
public static TEntity IfNullThrowException<TEntity>(this TEntity? businessStruct) where TEntity : struct
{
if (businessStruct == null)
{
throw new QueryBusinessObjectNotExistException($"The query object {typeof(TEntity).Name} does not exist , or was deleted by someone else, or an incorrect parameter query caused");
}
else
{
return (TEntity)businessStruct;
}
}
[DoesNotReturn]
public static TEntity IfNullThrowConvertException<TEntity>(this TEntity businessObject) where TEntity : class
{
if (businessObject == null)
{
throw new QueryBusinessObjectNotExistException($" Can not Convert to {typeof(TEntity).Name} Type, Please check parameter");
}
else
{
return businessObject!;
}
}
}
public class QueryBusinessObjectNotExistException : Exception
{
public QueryBusinessObjectNotExistException()
{
}
public QueryBusinessObjectNotExistException(string message) : base(message)
{
}
}
public class ConversionException : Exception
{
public ConversionException(string message) : base(message)
{
}
}
}
@@ -0,0 +1,59 @@
using System.Collections.Generic;
using System.Linq;
namespace IRaCIS.Core.Infrastructure.Extention
{
/// <summary>
/// 分页信息输出 泛型
/// </summary>
public class PageOutput<T>
{
/// <summary>
/// 当前页索引
/// </summary>
public int PageIndex { get; set; }
/// <summary>
/// 每页的记录条数
/// </summary>
public int PageSize { get; set; }
/// <summary>
/// 数据总数
/// </summary>
public long TotalCount { get; set; } = 0;
/// <summary>
/// 数据
/// </summary>
public IList<T> CurrentPageData { get; set; }
/// <summary>
/// 分页数据 可能额外返回其他类型的查询数据 必须一些配置
/// </summary>
public object OtherData { get; set; }
public PageOutput()
{
}
public PageOutput(int pageIndex, int pageSize, long totalCount, IList<T> data)
{
PageIndex = pageIndex;
PageSize = pageSize;
TotalCount = totalCount;
CurrentPageData = data;
}
public PageOutput(int pageIndex, int pageSize, IQueryable<T> list)
{
PageIndex = pageIndex;
PageSize = pageSize;
TotalCount = list.Count();
CurrentPageData = list.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
}
}
}
@@ -0,0 +1,206 @@
using Newtonsoft.Json;
namespace IRaCIS.Core.Infrastructure.Extention
{
/// <summary>
/// 响应数据输出 泛型
/// </summary>
public class ResponseOutput<T> : IResponseOutput<T>
{
/// <summary>
/// 是否成功标记
/// </summary>
public bool IsSuccess { get; private set; }
public ApiResponseCodeEnum Code { get; set; } = ApiResponseCodeEnum.OK;
/// <summary>
/// 消息
/// </summary>
public string ErrorMessage { get; private set; }
/// <summary>
/// 数据 兼顾以前 Json序列化的时候返回属性名为“Result”
/// </summary>
[JsonProperty("Result")]
public T Data { get; private set; }
public object OtherData { get; set; }
/// <summary>
/// 成功
/// </summary>
/// <param name="data">数据</param>
/// <param name="msg">消息</param>
//public ResponseOutput<T> Ok(T data, string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.OK)
//{
// IsSuccess = true;
// Code = code;
// Data = data;
// ErrorMessage = msg;
// return this;
//}
public ResponseOutput<T> Ok(T data, object otherData, string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.OK)
{
IsSuccess = true;
Code = code;
Data = data;
OtherData=otherData;
ErrorMessage = msg;
return this;
}
/// <summary>
/// 失败
/// </summary>
/// <param name="msg">提示消息</param>
/// <param name="data">数据</param>
/// <returns></returns>
public ResponseOutput<T> NotOk(string msg = "", T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.OK)
{
IsSuccess = false;
Code = code;
ErrorMessage = msg;
Data = data;
return this;
}
}
public class ResponseOutput<T, T2> : IResponseOutput<T, T2>
{
[JsonProperty("Result")]
public T Data { get; private set; }
public T2 OtherInfo { get; private set; }
public bool IsSuccess { get; private set; }
public ApiResponseCodeEnum Code { get; set; }
public string ErrorMessage { get; private set; }
public ResponseOutput<T, T2> Ok(T data, T2 otherInfo, string msg = "")
{
IsSuccess = true;
Data = data;
OtherInfo = otherInfo;
ErrorMessage = msg;
return this;
}
}
/// <summary>
/// 响应数据静态输出 为了代码简洁 不用每处都New
/// </summary>
public static class ResponseOutput
{
public static IResponseOutput<T, T2> Ok<T, T2>(T data, T2 otherInfo, string msg = "")
{
return new ResponseOutput<T, T2>().Ok(data, otherInfo);
}
/// <summary>
/// 成功 -----适合查询
/// </summary>
/// <param name="data">数据</param>
/// <param name="msg">消息</param>
/// <returns></returns>
//public static IResponseOutput<T> Ok<T>(T data = default, string msg = "")
//{
// return new ResponseOutput<T>().Ok(data, msg);
//}
public static IResponseOutput<T> Ok<T>(T data = default, object otherData = default, string msg = "")
{
return new ResponseOutput<T>().Ok(data, otherData, msg);
}
/// <summary>
/// 成功
/// </summary>
/// <returns></returns>
public static IResponseOutput Ok()
{
return Ok<string>();
}
/// <summary>
/// 失败
/// </summary>
/// <param name="msg">消息</param>
/// <param name="data">数据</param>
/// <returns></returns>
public static IResponseOutput<T> NotOk<T>(string msg = "", T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.OK)
{
return new ResponseOutput<T>().NotOk(msg, data, code);
}
public static IResponseOutput<T> NotOk<T>( T data = default, ApiResponseCodeEnum code = ApiResponseCodeEnum.OK)
{
return new ResponseOutput<T>().NotOk("", data, code);
}
/// <summary>
/// 失败
/// </summary>
/// <param name="msg">消息</param>
/// <returns></returns>
public static IResponseOutput<string> NotOk(string msg = "", ApiResponseCodeEnum code = ApiResponseCodeEnum.OK)
{
return new ResponseOutput<string>().NotOk(msg,code:code);
}
public static IResponseOutput<string> DBNotExistIfNUll(object businessObject)
{
return new ResponseOutput<string>().NotOk($"The business object{businessObject.GetType().Name} does not exist in the database, or was deleted by someone else, or an incorrect parameter query caused");
}
/// <summary>
/// 根据布尔值返回结果 --适合删除
/// </summary>
/// <param name="success"></param>
/// <returns></returns>
public static IResponseOutput Result(bool success)
{
return success ? Ok() : NotOk("Expect a change, but the database data has not changed");
}
/// <summary>
/// 根据布尔值返回结果 --适合添加和更新一起
/// </summary>
/// <param name="success"></param>
/// <returns></returns>
public static IResponseOutput<T> Result<T>(bool success, T data = default)
{
return success ? Ok<T>(data) : NotOk<T>("Saved failed");
}
///// <summary>
///// 根据布尔值返回结果
///// </summary>
///// <param name="success"></param>
///// <returns></returns>
//public static IResponseOutput Result<T>(bool success)
//{
// return success ? Ok<T>() : NotOk<T>();
//}
}
}
@@ -0,0 +1,158 @@
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace IRaCIS.Core.Infrastructure.Extention
{
public static class HttpContextExtension
{
public static T GetService<T>(this HttpContext context) where T : class
{
return context.RequestServices.GetService(typeof(T)) as T;
}
public static string GetUserIp(this HttpContext context)
{
string realIP = null;
string forwarded = null;
string remoteIpAddress = context.Connection.RemoteIpAddress.ToString();
if (context.Request.Headers.ContainsKey("X-Real-IP"))
{
realIP = context.Request.Headers["X-Real-IP"].ToString();
if (realIP != remoteIpAddress)
{
remoteIpAddress = realIP;
}
}
if (context.Request.Headers.ContainsKey("X-Forwarded-For"))
{
forwarded = context.Request.Headers["X-Forwarded-For"].ToString();
if (forwarded != remoteIpAddress)
{
remoteIpAddress = forwarded;
}
}
return remoteIpAddress;
}
/// <summary>
/// 获取Request值
/// </summary>
/// <param name="context"></param>
/// <param name="parameter"></param>
/// <returns></returns>
public static string Request(this HttpContext context, string parameter)
{
try
{
if (context == null)
return null;
if (context.Request.Method == "POST")
return context.Request.Form[parameter].ToString();
else
return context.Request.Query[parameter].ToString();
}
catch (System.Exception ex)
{
Console.Write(ex.Message + ex.InnerException);
return context.RequestString(parameter);
}
}
public static T Request<T>(this HttpContext context, string parameter) where T : class
{
return context.RequestString(parameter)?.DeserializeObject<T>();
}
public static string RequestString(this HttpContext context, string parameter)
{
string requestParam = context.GetRequestParameters();
if (string.IsNullOrEmpty(requestParam)) return null;
Dictionary<string, object> keyValues = requestParam.DeserializeObject<Dictionary<string, object>>();
if (keyValues == null || keyValues.Count == 0) return null;
if (keyValues.TryGetValue(parameter, out object value))
{
if (value == null) return null;
if (value.GetType() == typeof(string))
{
return value?.ToString();
}
return value.Serialize();
}
return null;
}
/// <summary>
/// 是否为ajax请求
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public static bool IsAjaxRequest(this HttpContext context)
{
return context.Request("X-Requested-With") == "XMLHttpRequest"
|| (context.Request.Headers != null
&& context.Request.Headers["X-Requested-With"] == "XMLHttpRequest");
}
public static UserAgent GetAgentType(this HttpContext context)
{
string agent = context.Request.Headers["User-Agent"].ToString().ToLower();
if (agent.Contains("ios") || agent.Contains("ipod") || agent.Contains("ipad"))
{
return UserAgent.IOS;
}
if (agent.Contains("windows"))
{
return UserAgent.Windows;
}
return UserAgent.Android;
}
/// <summary>
/// 获取请求的参数
/// net core 2.0已增加回读方法 context.Request.EnableRewind();
///
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static string GetRequestParameters(this HttpContext context)
{
if (context.Request.Body == null || !context.Request.Body.CanRead || !context.Request.Body.CanSeek)
return null;
if (context.Request.Body.Length == 0)
return null;
if (context.Request.Body.Position > 0)
context.Request.Body.Position = 0;
string prarameters = null;
var bodyStream = context.Request.Body;
using (var buffer = new MemoryStream())
{
bodyStream.CopyToAsync(buffer);
buffer.Position = 0L;
bodyStream.Position = 0L;
using (var reader = new StreamReader(buffer, Encoding.UTF8))
{
buffer.Seek(0, SeekOrigin.Begin);
prarameters = reader.ReadToEnd();
}
}
return prarameters;
}
}
public enum UserAgent
{
IOS = 0,
Android = 1,
Windows = 2,
Linux
}
}
@@ -0,0 +1,205 @@
using SharpCompress.Archives;
using SharpCompress.Common;
using SharpCompress.Readers;
using SharpCompress.Writers;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace IRaCIS.Core.Infrastructure.Extention
{
/// <summary>
/// 7z压缩
/// </summary>
public static class SevenZipCompressor
{
/// <summary>
/// 将多个文件压缩到一个内存流中,可保存为zip文件,方便于web方式下载
/// </summary>
/// <param name="files">多个文件路径,文件或文件夹,或网络路径http/https</param>
/// <param name="rootdir"></param>
/// <returns>文件流</returns>
public static MemoryStream ZipStream(List<string> files, string rootdir = "")
{
using var archive = CreateZipArchive(files, rootdir);
var ms = new MemoryStream();
archive.SaveTo(ms, new WriterOptions(CompressionType.Deflate)
{
LeaveStreamOpen = true,
ArchiveEncoding = new ArchiveEncoding()
{
Default = Encoding.UTF8
}
});
return ms;
}
/// <summary>
/// 压缩多个文件
/// </summary>
/// <param name="files">多个文件路径,文件或文件夹</param>
/// <param name="zipFile">压缩到...</param>
/// <param name="rootdir">压缩包内部根文件夹</param>
/// <param name="archiveType"></param>
public static void Zip(List<string> files, string zipFile, string rootdir = "", ArchiveType archiveType = ArchiveType.SevenZip)
{
using var archive = CreateZipArchive(files, rootdir, archiveType);
archive.SaveTo(zipFile, new WriterOptions(CompressionType.Deflate)
{
LeaveStreamOpen = true,
ArchiveEncoding = new ArchiveEncoding()
{
Default = Encoding.UTF8
}
});
}
/// <summary>
/// 解压文件,自动检测压缩包类型
/// </summary>
/// <param name="compressedFile">rar文件</param>
/// <param name="dir">解压到...</param>
/// <param name="ignoreEmptyDir">忽略空文件夹</param>
public static void Decompress(string compressedFile, string dir = "", bool ignoreEmptyDir = true)
{
if (string.IsNullOrEmpty(dir))
{
dir = Path.GetDirectoryName(compressedFile);
}
using Stream stream = File.OpenRead(compressedFile);
using var reader = ReaderFactory.Open(stream);
while (reader.MoveToNextEntry())
{
if (ignoreEmptyDir)
{
reader.WriteEntryToDirectory(dir, new ExtractionOptions()
{
ExtractFullPath = true,
Overwrite = true
});
}
else
{
if (!reader.Entry.IsDirectory)
{
reader.WriteEntryToDirectory(dir, new ExtractionOptions()
{
ExtractFullPath = true,
Overwrite = true
});
}
}
}
}
/// <summary>
/// 创建zip包
/// </summary>
/// <param name="files"></param>
/// <param name="rootdir"></param>
/// <param name="archiveType"></param>
/// <returns></returns>
private static IWritableArchive CreateZipArchive(List<string> files, string rootdir, ArchiveType archiveType = ArchiveType.SevenZip)
{
var archive = ArchiveFactory.Create(archiveType);
var dic = GetFileEntryMaps(files);
var remoteUrls = files.Distinct().Where(s => s.StartsWith("http")).Select(s =>
{
try
{
return new Uri(s);
}
catch (UriFormatException)
{
return null;
}
}).Where(u => u != null).ToList();
foreach (var pair in dic)
{
archive.AddEntry(Path.Combine(rootdir, pair.Value), pair.Key);
}
if (!remoteUrls.Any())
{
return archive;
}
var streams = new ConcurrentDictionary<string, Stream>();
using var httpClient = new HttpClient();
Parallel.ForEach(remoteUrls, url =>
{
httpClient.GetAsync(url).ContinueWith(async t =>
{
if (t.IsCompleted)
{
var res = await t;
if (res.IsSuccessStatusCode)
{
Stream stream = await res.Content.ReadAsStreamAsync();
streams[Path.Combine(rootdir, Path.GetFileName(HttpUtility.UrlDecode(url.AbsolutePath)))] = stream;
}
}
}).Wait();
});
foreach (var kv in streams)
{
archive.AddEntry(kv.Key, kv.Value, true);
}
return archive;
}
/// <summary>
/// 获取文件路径和zip-entry的映射
/// </summary>
/// <param name="files"></param>
/// <returns></returns>
private static Dictionary<string, string> GetFileEntryMaps(List<string> files)
{
var fileList = new List<string>();
void GetFilesRecurs(string path)
{
//遍历目标文件夹的所有文件
fileList.AddRange(Directory.GetFiles(path));
//遍历目标文件夹的所有文件夹
foreach (string directory in Directory.GetDirectories(path))
{
GetFilesRecurs(directory);
}
}
files.Where(s => !s.StartsWith("http")).ForEach(s =>
{
if (Directory.Exists(s))
{
GetFilesRecurs(s);
}
else
{
fileList.Add(s);
}
});
if (!fileList.Any())
{
return new Dictionary<string, string>();
}
var dirname = new string(fileList.First().Substring(0, fileList.Min(s => s.Length)).TakeWhile((c, i) => fileList.All(s => s[i] == c)).ToArray());
if (!Directory.Exists(dirname))
{
dirname = Directory.GetParent(dirname).FullName;
}
var dic = fileList.ToDictionary(s => s, s => s.Substring(dirname.Length));
return dic;
}
}
}