懒得勤快 3 vuotta sitten
vanhempi
sitoutus
bd25a121f8

+ 3 - 2
Masuit.Tools.Abstractions/Masuit.Tools.Abstractions.csproj

@@ -3,7 +3,7 @@
         <TargetFrameworks>netstandard2.0;netstandard2.1;net461;net5;net6</TargetFrameworks>
         <LangVersion>latest</LangVersion>
         <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-        <Version>2.5.6</Version>
+        <Version>2.5.6.1</Version>
         <Authors>懒得勤快</Authors>
         <Description>Masuit.Tools基础公共库,包含一些常用的操作类,大都是静态类,加密解密,反射操作,Excel简单导出,权重随机筛选算法,分布式短id,表达式树,linq扩展,文件压缩,多线程下载和FTP客户端,硬件信息,字符串扩展方法,日期时间扩展操作,中国农历,大文件拷贝,图像裁剪,验证码,断点续传,集合扩展等常用封装。</Description>
         <Copyright>懒得勤快,长空X</Copyright>
@@ -43,7 +43,8 @@
     </ItemGroup>
 
     <ItemGroup>
-        <PackageReference Include="DnsClient" Version="1.6.1" />
+        <PackageReference Include="DnsClient" Version="1.7.0" />
+        <PackageReference Include="FastExpressionCompiler" Version="3.3.3" />
         <PackageReference Include="HtmlSanitizer" Version="8.0.601" />
         <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
         <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />

+ 1 - 1
Masuit.Tools.AspNetCore/Masuit.Tools.AspNetCore.csproj

@@ -17,7 +17,7 @@
         <Product>Masuit.Tools.AspNetCore</Product>
         <PackageId>Masuit.Tools.AspNetCore</PackageId>
         <LangVersion>latest</LangVersion>
-        <Version>1.1.6</Version>
+        <Version>1.1.6.1</Version>
         <RepositoryType></RepositoryType>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
         <FileVersion>$(Version)</FileVersion>

+ 69 - 13
Masuit.Tools.Core/AspNetCore/DbSetExtensions.cs

@@ -1,11 +1,8 @@
-using Microsoft.EntityFrameworkCore;
-using System;
-using System.Collections.Generic;
+using FastExpressionCompiler;
+using Microsoft.EntityFrameworkCore;
 using System.ComponentModel.DataAnnotations;
-using System.Linq;
 using System.Linq.Expressions;
 using System.Reflection;
-
 namespace Masuit.Tools.Core.AspNetCore
 {
     public static class DbSetExtensions
@@ -20,10 +17,7 @@ namespace Masuit.Tools.Core.AspNetCore
         /// <param name="entities"></param>
         public static void AddOrUpdate<T, TKey>(this DbSet<T> dbSet, Expression<Func<T, TKey>> keySelector, params T[] entities) where T : class
         {
-            foreach (var entity in entities)
-            {
-                AddOrUpdate(dbSet, keySelector, entity);
-            }
+            AddOrUpdate(dbSet, keySelector, entities.AsEnumerable());
         }
 
         /// <summary>
@@ -36,9 +30,71 @@ namespace Masuit.Tools.Core.AspNetCore
         /// <param name="entities"></param>
         public static void AddOrUpdate<T, TKey>(this DbSet<T> dbSet, Expression<Func<T, TKey>> keySelector, IEnumerable<T> entities) where T : class
         {
-            foreach (var entity in entities)
+            if (keySelector == null)
+            {
+                throw new ArgumentNullException(nameof(keySelector));
+            }
+
+            if (entities == null)
+            {
+                throw new ArgumentNullException(nameof(entities));
+            }
+
+            if (entities is not ICollection<T> collection)
+            {
+                collection = entities.ToList();
+            }
+
+            var func = keySelector.CompileFast();
+            var keyObjects = collection.Select(s => func(s)).ToList();
+            var parameter = keySelector.Parameters[0];
+            var array = Expression.Constant(keyObjects);
+            var call = Expression.Call(array, typeof(List<TKey>).GetMethod(nameof(List<TKey>.Contains)), keySelector.Body);
+            var lambda = Expression.Lambda<Func<T, bool>>(call, parameter);
+            var items = dbSet.Where(lambda).ToDictionary(t => func(t));
+            foreach (var entity in collection)
             {
-                AddOrUpdate(dbSet, keySelector, entity);
+                var key = func(entity);
+                if (items.ContainsKey(key))
+                {
+                    // 获取主键字段
+                    var dataType = typeof(T);
+                    var keyIgnoreFields = dataType.GetProperties().Where(p => p.GetCustomAttribute<KeyAttribute>() != null || p.GetCustomAttribute<UpdateIgnoreAttribute>() != null).ToList();
+                    if (!keyIgnoreFields.Any())
+                    {
+                        string idName = dataType.Name + "Id";
+                        keyIgnoreFields = dataType.GetProperties().Where(p => p.Name.Equals("Id", StringComparison.OrdinalIgnoreCase) || p.Name.Equals(idName, StringComparison.OrdinalIgnoreCase)).ToList();
+                    }
+
+                    // 更新所有非主键属性
+                    foreach (var p in typeof(T).GetProperties().Where(p => p.GetSetMethod() != null && p.GetGetMethod() != null))
+                    {
+                        // 忽略主键和被忽略的字段
+                        if (keyIgnoreFields.Any(x => x.Name == p.Name))
+                        {
+                            continue;
+                        }
+
+                        var existingValue = p.GetValue(items[key]);
+                        if (p.GetValue(items[key]) != existingValue)
+                        {
+                            p.SetValue(items[key], existingValue);
+                        }
+                    }
+
+                    foreach (var idField in keyIgnoreFields.Where(p => p.SetMethod != null && p.GetMethod != null))
+                    {
+                        var existingValue = idField.GetValue(items[key]);
+                        if (idField.GetValue(items[key]) != existingValue)
+                        {
+                            idField.SetValue(items[key], existingValue);
+                        }
+                    }
+                }
+                else
+                {
+                    dbSet.Add(entity);
+                }
             }
         }
 
@@ -62,8 +118,8 @@ namespace Masuit.Tools.Core.AspNetCore
                 throw new ArgumentNullException(nameof(entity));
             }
 
-            var keyObject = keySelector.Compile()(entity);
-            var parameter = Expression.Parameter(typeof(T), "p");
+            var keyObject = keySelector.CompileFast()(entity);
+            var parameter = keySelector.Parameters[0];
             var lambda = Expression.Lambda<Func<T, bool>>(Expression.Equal(ReplaceParameter(keySelector.Body, parameter), Expression.Constant(keyObject)), parameter);
             var item = dbSet.FirstOrDefault(lambda);
             if (item == null)

+ 1 - 10
Masuit.Tools.Core/Masuit.Tools.Core.csproj

@@ -20,7 +20,7 @@ github:https://github.com/ldqk/Masuit.Tools
         <UserSecretsId>830c282f-f7c1-42be-8651-4cd06ac8e73f</UserSecretsId>
         <RepositoryType></RepositoryType>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
-        <Version>2.5.6</Version>
+        <Version>2.5.6.1</Version>
         <FileVersion>$(Version)</FileVersion>
         <Company>masuit.org</Company>
         <AssemblyVersion>$(Version)</AssemblyVersion>
@@ -35,18 +35,9 @@ github:https://github.com/ldqk/Masuit.Tools
     </PropertyGroup>
 
     <ItemGroup>
-        <PackageReference Include="DnsClient" Version="1.6.1" />
-        <PackageReference Include="HtmlSanitizer" Version="8.0.601" />
         <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
-        <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
         <PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
-        <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="6.0.1" />
         <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
-        <PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
-        <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta15" />
-        <PackageReference Include="System.Management" Version="6.0.0" />
-        <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
-        <PackageReference Include="SharpCompress" Version="0.32.2" />
     </ItemGroup>
 
     <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">

+ 3 - 2
Masuit.Tools.Core/Net/WebExtension.cs

@@ -1,4 +1,5 @@
-using Microsoft.AspNetCore.Http;
+using FastExpressionCompiler;
+using Microsoft.AspNetCore.Http;
 using Newtonsoft.Json;
 using System.Linq.Expressions;
 
@@ -34,7 +35,7 @@ namespace Masuit.Tools.Core.Net
             {
                 return typeof(T).Namespace switch
                 {
-                    "System.Collections.Generic" => (T)(Expression.Lambda(Expression.New(typeof(T))).Compile().DynamicInvoke()),
+                    "System.Collections.Generic" => (T)(Expression.Lambda(Expression.New(typeof(T))).CompileFast().DynamicInvoke()),
                     _ => default
                 };
             }

+ 1 - 1
Masuit.Tools.Net45/Masuit.Tools.Net45.csproj

@@ -304,7 +304,7 @@
   </ItemGroup>
   <ItemGroup>
     <PackageReference Include="DnsClient">
-      <Version>1.6.1</Version>
+      <Version>1.7.0</Version>
     </PackageReference>
     <PackageReference Include="Microsoft.AspNet.Mvc">
       <Version>5.2.9</Version>

+ 1 - 1
Masuit.Tools/Masuit.Tools.csproj

@@ -174,7 +174,7 @@
   </ItemGroup>
   <ItemGroup>
     <PackageReference Include="DnsClient">
-      <Version>1.6.1</Version>
+      <Version>1.7.0</Version>
     </PackageReference>
     <PackageReference Include="HtmlSanitizer">
       <Version>8.0.601</Version>

+ 1 - 1
Masuit.Tools/package.nuspec

@@ -2,7 +2,7 @@
 <package>
   <metadata>
     <id>Masuit.Tools.Net</id>
-    <version>2.5.6</version>
+    <version>2.5.6.1</version>
     <title>Masuit.Tools</title>
     <authors>懒得勤快</authors>
     <owners>masuit.com</owners>