From a8ad85ccab3cea5a8de87d7e08674f8a70c8c049 Mon Sep 17 00:00:00 2001
From: schangxiang@126.com <schangxiang@126.com>
Date: 周三, 24 4月 2024 11:14:17 +0800
Subject: [PATCH] 1
---
iWare_RawMaterialWarehouse_Wms/Admin.NET.EntityFramework.Core/DbContexts/DefaultDbContext.cs | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 307 insertions(+), 0 deletions(-)
diff --git a/iWare_RawMaterialWarehouse_Wms/Admin.NET.EntityFramework.Core/DbContexts/DefaultDbContext.cs b/iWare_RawMaterialWarehouse_Wms/Admin.NET.EntityFramework.Core/DbContexts/DefaultDbContext.cs
new file mode 100644
index 0000000..71bd224
--- /dev/null
+++ b/iWare_RawMaterialWarehouse_Wms/Admin.NET.EntityFramework.Core/DbContexts/DefaultDbContext.cs
@@ -0,0 +1,307 @@
+using Admin.NET.Core;
+using Admin.NET.Core.Entity;
+using Furion;
+using Furion.DatabaseAccessor;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Diagnostics;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using System.Linq.Expressions;
+using Yitter.IdGenerator;
+
+namespace Admin.NET.EntityFramework.Core
+{
+ [AppDbContext("DefaultConnection", DbProvider.SqlServer)]
+ public class DefaultDbContext : AppDbContext<DefaultDbContext>, IModelBuilderFilter
+ {
+ public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
+ {
+ // 鍚敤瀹炰綋鏁版嵁鏇存敼鐩戝惉
+ EnabledEntityChangedListener = true;
+
+ // 蹇界暐绌哄�兼洿鏂�
+ InsertOrUpdateIgnoreNullValues = true;
+ }
+
+ /// <summary>
+ /// 鑾峰彇绉熸埛Id
+ /// </summary>
+ /// <returns></returns>
+ //public object GetTenantId()
+ //{
+ // // 娴佺▼涓病鏈夌敤鍒板绉熸埛 杩欓噷榛樿杩斿洖涓�涓鎴�
+ // if (App.User == null) return 142307070918780;
+ // return Convert.ToInt64(App.User.FindFirst(ClaimConst.TENANT_ID)?.Value);
+ //}
+
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ if (Database.ProviderName == DbProvider.Sqlite)
+ {
+ // SQLite does not have proper support for DateTimeOffset via Entity Framework Core, see the limitations
+ // here: https://docs.microsoft.com/en-us/ef/core/providers/sqlite/limitations#query-limitations
+ // To work around this, when the Sqlite database provider is used, all model properties of type DateTimeOffset
+ // use the DateTimeOffsetToBinaryConverter
+ // Based on: https://github.com/aspnet/EntityFrameworkCore/issues/10784#issuecomment-415769754
+ // This only supports millisecond precision, but should be sufficient for most use cases.
+ foreach (var entityType in builder.Model.GetEntityTypes())
+ {
+ var properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTimeOffset)
+ || p.PropertyType == typeof(DateTimeOffset?));
+ foreach (var property in properties)
+ {
+ builder
+ .Entity(entityType.Name)
+ .Property(property.Name)
+ .HasConversion(new DateTimeOffsetToBinaryConverter());
+ }
+ }
+ }
+ // 澶勭悊mysql鏃跺尯闂 https://gitee.com/dotnetchina/Furion/issues/I3RSCO#note_5685893_link
+ else if (Database.ProviderName == DbProvider.MySql || Database.ProviderName == DbProvider.MySqlOfficial)
+ {
+ var converter = new ValueConverter<DateTimeOffset, DateTime>(v => v.LocalDateTime, v => v);
+
+ // 鎵弿绋嬪簭闆嗭紝鑾峰彇鏁版嵁搴撳疄浣撶浉鍏崇被鍨�
+ var types = App.EffectiveTypes.Where(t => (typeof(IPrivateEntity).IsAssignableFrom(t) || typeof(IPrivateModelBuilder).IsAssignableFrom(t))
+ && t.IsClass && !t.IsAbstract && !t.IsGenericType && !t.IsInterface && !t.IsDefined(typeof(ManualAttribute), true));
+
+ if (types.Any())
+ {
+ foreach (var item in types)
+ {
+ if (item.IsSubclassOf(typeof(DEntityBase)) || item.IsSubclassOf(typeof(EntityBase)))
+ {
+ foreach (var property in item.GetProperties())
+ {
+ if (property.PropertyType == typeof(DateTimeOffset?) || property.PropertyType == typeof(DateTimeOffset))
+ {
+ builder.Entity(item).Property(property.Name).HasConversion(converter);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ base.OnModelCreating(builder);
+ }
+
+ /// <summary>
+ /// 閰嶇疆绉熸埛Id杩囨护鍣�
+ /// </summary>
+ /// <param name="modelBuilder"></param>
+ /// <param name="entityBuilder"></param>
+ /// <param name="dbContext"></param>
+ /// <param name="dbContextLocator"></param>
+ public void OnCreating(ModelBuilder modelBuilder, EntityTypeBuilder entityBuilder, DbContext dbContext, Type dbContextLocator)
+ {
+ // 閰嶇疆鍋囧垹闄よ繃婊ゅ櫒
+ LambdaExpression expression = FakeDeleteQueryFilterExpression(entityBuilder, dbContext);
+ if (expression != null)
+ entityBuilder.HasQueryFilter(expression);
+ // 閰嶇疆鏁版嵁鏉冮檺鍔ㄦ�佽〃杈惧紡
+ LambdaExpression dataScopesExpression = DataScopesFilterExpression(entityBuilder, dbContext);
+ if (dataScopesExpression != null)
+ entityBuilder.HasQueryFilter(dataScopesExpression);
+ }
+
+ protected override void SavingChangesEvent(DbContextEventData eventData, InterceptionResult<int> result)
+ {
+ // 鑾峰彇褰撳墠浜嬩欢瀵瑰簲涓婁笅鏂�
+ var dbContext = eventData.Context;
+ // 鑾峰彇鎵�鏈夋洿鏀癸紝鍒犻櫎锛屾柊澧炵殑瀹炰綋锛屼絾鎺掗櫎瀹¤瀹炰綋锛堥伩鍏嶆寰幆锛�
+ var entities = dbContext.ChangeTracker.Entries()
+ .Where(u => u.Entity.GetType() != typeof(SysLogAudit) && u.Entity.GetType() != typeof(SysLogOp) &&
+ u.Entity.GetType() != typeof(SysLogVis) && u.Entity.GetType() != typeof(SysLogEx) &&
+ (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added)).ToList();
+ if (entities == null || entities.Count < 1) return;
+
+ //// 鍒ゆ柇鏄惁鏄紨绀虹幆澧�
+ //var demoEnvFlag = App.GetService<ISysConfigService>().GetDemoEnvFlag().GetAwaiter().GetResult();
+ //if (demoEnvFlag)
+ //{
+ // var sysUser = entities.Find(u => u.Entity.GetType() == typeof(SysUser));
+ // if (sysUser == null || string.IsNullOrEmpty((sysUser.Entity as SysUser).LastLoginTime.ToString())) // 鎺掗櫎鐧诲綍
+ // throw Oops.Oh(ErrorCode.D1200);
+ //}
+
+ // 褰撳墠鎿嶄綔鑰呬俊鎭�
+ var userId = App.User?.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
+ //璇诲彇鐨勭敤鎴峰悕鏀逛负 鏄电О锛岃�屼笉鏄处鍙� 銆怑ditby shaocx,2024-04-20銆�
+ //var userName = App.User?.FindFirst(ClaimConst.CLAINM_ACCOUNT)?.Value;
+ var userName = App.User?.FindFirst(ClaimConst.CLAINM_NAME)?.Value;
+ // 褰撳墠鎿嶄綔鑰呮満鏋勪俊鎭�
+ var orgId = App.User?.FindFirst(ClaimConst.CLAINM_ORGID)?.Value;
+ var orgName = App.User?.FindFirst(ClaimConst.CLAINM_ORGNAME)?.Value;
+
+ foreach (var entity in entities)
+ {
+ if (entity.Entity.GetType().IsSubclassOf(typeof(DEntityBase)))
+ {
+ var obj = entity.Entity as DEntityBase;
+ if (entity.State == EntityState.Added)
+ {
+ obj.Id = obj.Id == 0 ? YitIdHelper.NextId() : obj.Id;
+ obj.CreatedTime = DateTimeOffset.Now;
+ if (!string.IsNullOrEmpty(userId))
+ {
+ obj.CreatedUserId = long.Parse(userId);
+ obj.CreatedUserName = userName;
+ if (entity.Entity.GetType().GetInterface(typeof(IDataPermissions).Name) != null)
+ {
+ ((IDataPermissions)obj).CreatedUserOrgId = long.Parse(orgId);
+ ((IDataPermissions)obj).CreatedUserOrgName = orgName;
+ }
+ }
+ }
+ else if (entity.State == EntityState.Modified)
+ {
+ // 鎺掗櫎鍒涘缓浜�
+ entity.Property(nameof(DEntityBase.CreatedUserId)).IsModified = false;
+ entity.Property(nameof(DEntityBase.CreatedUserName)).IsModified = false;
+ // 鎺掗櫎鍒涘缓鏃ユ湡
+ entity.Property(nameof(DEntityBase.CreatedTime)).IsModified = false;
+
+ obj.UpdatedTime = DateTimeOffset.Now;
+ if (!string.IsNullOrEmpty(userId))
+ {
+ obj.UpdatedUserId = long.Parse(userId);
+ obj.UpdatedUserName = userName;
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// 鏋勫缓绉熸埛Id浠ュ強鍋囧垹闄よ繃婊ゅ櫒
+ /// </summary>
+ /// <param name="entityBuilder"></param>
+ /// <param name="dbContext"></param>
+ /// <param name="isDeletedKey"></param>
+ /// <param name="filterValue"></param>
+ /// <returns></returns>
+ protected static LambdaExpression FakeDeleteQueryFilterExpression(EntityTypeBuilder entityBuilder, DbContext dbContext, string onTableTenantId = null, string isDeletedKey = null, object filterValue = null)
+ {
+ //onTableTenantId ??= "TenantId";
+ isDeletedKey ??= "IsDeleted";
+ IMutableEntityType metadata = entityBuilder.Metadata;
+ //if (metadata.FindProperty(onTableTenantId) == null && metadata.FindProperty(isDeletedKey) == null)
+ //{
+ // return null;
+ //}
+ //瑙e喅瀹炰綋缁ф壙鎶ラ敊闂锛屽熀绫昏〃鎵嶆湁IsDeleted銆乀enantId瀛楁
+ if (metadata.BaseType != null)
+ {
+ return null;
+ }
+
+ Expression finialExpression = Expression.Constant(true);
+ ParameterExpression parameterExpression = Expression.Parameter(metadata.ClrType, "u");
+
+
+ // 鍋囧垹闄よ繃婊ゅ櫒
+ if (metadata.FindProperty(isDeletedKey) != null)
+ {
+ ConstantExpression constantExpression = Expression.Constant(isDeletedKey);
+ ConstantExpression right = Expression.Constant(filterValue ?? false);
+ var fakeDeleteQueryExpression = Expression.Equal(Expression.Call(typeof(EF), "Property", new Type[1]
+ {
+ typeof(bool)
+ }, parameterExpression, constantExpression), right);
+ finialExpression = Expression.AndAlso(finialExpression, fakeDeleteQueryExpression);
+ }
+
+ return Expression.Lambda(finialExpression, parameterExpression);
+ }
+
+ #region 鏁版嵁鏉冮檺
+
+ /// <summary>
+ /// 鑾峰彇鐢ㄦ埛Id
+ /// </summary>
+ /// <returns></returns>
+ public object GetUserId()
+ {
+ if (App.User == null) return null;
+ return App.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
+ }
+
+ /// <summary>
+ /// 鑾峰彇鏁版嵁鑼冨洿
+ /// </summary>
+ /// <returns></returns>
+ public List<object> GetDataScopes()
+ {
+ var userId = this.GetUserId();
+ if (userId == null)
+ {
+ return new List<object>();
+ }
+
+ var dataScopes = JsonUtil.FromJson<List<object>>(App.User.FindFirst(ClaimConst.DATA_SCOPES)?.Value);
+ if (dataScopes != null)
+ {
+ return dataScopes;
+ }
+ return new List<object>();
+ }
+
+ /// <summary>
+ /// 鏋勫缓鏁版嵁鑼冨洿杩囨护鍣�
+ /// </summary>
+ /// <param name="entityBuilder"></param>
+ /// <param name="dbContext"></param>
+ /// <param name="onTableCreatedUserId"></param>
+ /// <param name="onTableCreatedUserOrgId"></param>
+ /// <param name="filterValue"></param>
+ /// <returns></returns>
+ protected LambdaExpression DataScopesFilterExpression(EntityTypeBuilder entityBuilder, DbContext dbContext, string onTableCreatedUserId = null, string onTableCreatedUserOrgId = null)
+ {
+ onTableCreatedUserId ??= nameof(IDataPermissions.CreatedUserId);//鐢ㄦ埛id瀛楁
+ onTableCreatedUserOrgId ??= nameof(IDataPermissions.CreatedUserOrgId);//鐢ㄦ埛閮ㄩ棬瀛楁
+
+ IMutableEntityType metadata = entityBuilder.Metadata;
+ if (metadata.FindProperty(onTableCreatedUserId) == null || metadata.FindProperty(onTableCreatedUserOrgId) == null)
+ {
+ return null;
+ }
+
+ Expression finialExpression = Expression.Constant(true);
+ ParameterExpression parameterExpression = Expression.Parameter(metadata.ClrType, "u");
+
+ // 涓汉鐢ㄦ埛鏁版嵁杩囨护鍣�
+ if (metadata.FindProperty(onTableCreatedUserId) != null)
+ {
+ ConstantExpression constantExpression = Expression.Constant(onTableCreatedUserId);
+ MethodCallExpression right = Expression.Call(Expression.Constant(dbContext), dbContext.GetType().GetMethod("GetUserId"));
+ finialExpression = Expression.AndAlso(finialExpression, Expression.Equal(Expression.Call(typeof(EF), "Property", new Type[1]
+ {
+ typeof(object)
+ }, parameterExpression, constantExpression), right));
+ }
+
+ //鏁版嵁鏉冮檺杩囨护鍣�
+ if (metadata.FindProperty(onTableCreatedUserOrgId) != null)
+ {
+ ConstantExpression constantExpression = Expression.Constant(onTableCreatedUserOrgId);
+
+ MethodCallExpression dataScopesLeft = Expression.Call(Expression.Constant(dbContext), dbContext.GetType().GetMethod("GetDataScopes"));
+ var firstOrDefaultCall = Expression.Call(typeof(EF), "Property", new Type[1]
+ {
+ typeof(object)
+ }, parameterExpression, constantExpression);
+
+ var createdUserOrgIdQueryExpression = Expression.Call(dataScopesLeft, typeof(List<object>).GetMethod("Contains"), firstOrDefaultCall);
+
+ finialExpression = Expression.Or(finialExpression, createdUserOrgIdQueryExpression);
+ }
+
+ return Expression.Lambda(finialExpression, parameterExpression);
+ }
+
+ #endregion 鏁版嵁鏉冮檺
+ }
+}
\ No newline at end of file
--
Gitblit v1.9.3