浏览代码

添加导入导出功能

宝臣 王 3 月之前
父节点
当前提交
bf2d7aded9

+ 8 - 2
UniformMaterialManagementSystem/App.xaml.cs

@@ -27,7 +27,10 @@ namespace UniformMaterialManagementSystem
 
             this.InitializeComponent();
 
-            using var dbContext = new SqliteContext();
+            var optionsBuilderSource = new DbContextOptionsBuilder<SqliteContext>();
+            optionsBuilderSource.UseSqlite("Data Source=UniformMaterialManagementSystem.db");
+
+            using var dbContext = new SqliteContext(optionsBuilderSource.Options);
             dbContext.Database.Migrate();
         }
 
@@ -43,7 +46,10 @@ namespace UniformMaterialManagementSystem
             var services = new ServiceCollection();
 
             // DbContext 注册
-            services.AddDbContext<SqliteContext>();
+            services.AddDbContext<SqliteContext>(options =>
+            {
+                options.UseSqlite("Data Source=UniformMaterialManagementSystem.db");
+            });
 
             // View 注册
             services.AddSingleton<MainWindow>();

+ 2 - 2
UniformMaterialManagementSystem/Data/SqliteContext.cs

@@ -54,13 +54,13 @@ namespace UniformMaterialManagementSystem.Data
 
         public DbSet<FactoryLicense> FactoryLicenses { get; set; }
 
-        public SqliteContext() { }
+        //public SqliteContext() { }
 
         public SqliteContext(DbContextOptions<SqliteContext> options) : base(options) { }
 
         protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
         {
-            optionsBuilder.UseSqlite("Data Source=UniformMaterialManagementSystem.db");
+            //optionsBuilder.UseSqlite("Data Source=UniformMaterialManagementSystem.db");
 
             optionsBuilder
                 .LogTo(message => Debug.WriteLine(message), LogLevel.Information)

+ 155 - 15
UniformMaterialManagementSystem/Utils/DataBaseUtil.cs

@@ -1,4 +1,9 @@
-using Microsoft.EntityFrameworkCore;
+using System.IO;
+using System.Security.Cryptography;
+
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
 
 using UniformMaterialManagementSystem.Data;
 
@@ -6,47 +11,65 @@ namespace UniformMaterialManagementSystem.Utils
 {
     public static class DataBaseUtil
     {
-        public static void ExportTable<T>(string targetConnectionString) where T : class
+        private static readonly string DataBasePath = Environment.CurrentDirectory + "\\DataBase";
+        private const string Password = "88384e6a-07e0-47e9-8214-4470a16e78da";
+
+        public static async void ExportTable<T>(string targetConnectionString) where T : class
         {
+            CreateExportFolder();
+
             var optionsBuilderSource = new DbContextOptionsBuilder<SqliteContext>();
             optionsBuilderSource.UseSqlite("Data Source=UniformMaterialManagementSystem.db");
 
+            var targetPath = $"{DataBasePath}\\UniformMaterialManagementSystem.db";
+
             var optionsBuilderTarget = new DbContextOptionsBuilder<SqliteContext>();
-            optionsBuilderTarget.UseSqlite(targetConnectionString);
+            optionsBuilderTarget.UseSqlite($"Data Source={targetPath}");
 
-            using var sourceContext = new SqliteContext(optionsBuilderSource.Options);
-            using var targetContext = new SqliteContext(optionsBuilderTarget.Options);
+            await using var sourceContext = new SqliteContext(optionsBuilderSource.Options);
+            await using var targetContext = new SqliteContext(optionsBuilderTarget.Options);
 
             // 读取源数据
-            var sourceData = sourceContext.Set<T>().ToList();
+            var sourceData = await sourceContext.Set<T>()
+                .IncludeAll()
+                .ToListAsync();
 
             // 确保目标数据库创建
-            targetContext.Database.EnsureCreated();
+            await targetContext.Database.MigrateAsync();
 
             // 获取目标 DbSet
             var targetDbSet = targetContext.Set<T>();
 
             // 添加到目标数据库
             targetDbSet.AddRange(sourceData);
-            targetContext.SaveChanges();
+            await targetContext.SaveChangesAsync();
+
+            EncryptFile(targetPath, targetConnectionString);
         }
 
-        public static void ImportTable<T>(string sourceConnectionString) where T : class
+        public static async void ImportTable<T>(string sourceConnectionString) where T : class
         {
+            CreateExportFolder();
+
+            var sourcePath = $"{DataBasePath}\\UniformMaterialManagementSystem.db";
+            DecryptFile(sourceConnectionString, sourcePath);
+
             var optionsBuilderSource = new DbContextOptionsBuilder<SqliteContext>();
-            optionsBuilderSource.UseSqlite(sourceConnectionString);
+            optionsBuilderSource.UseSqlite($"Data Source={sourcePath}");
 
             var optionsBuilderTarget = new DbContextOptionsBuilder<SqliteContext>();
             optionsBuilderTarget.UseSqlite("Data Source=UniformMaterialManagementSystem.db");
 
-            using var sourceContext = new SqliteContext(optionsBuilderSource.Options);
-            using var targetContext = new SqliteContext(optionsBuilderTarget.Options);
+            await using var sourceContext = new SqliteContext(optionsBuilderSource.Options);
+            await using var targetContext = new SqliteContext(optionsBuilderTarget.Options);
 
             // 确保目标数据库创建
-            targetContext.Database.EnsureCreated();
+            await targetContext.Database.MigrateAsync();
 
             // 读取源数据
-            var sourceData = sourceContext.Set<T>().ToList();
+            var sourceData = sourceContext.Set<T>()
+                .IncludeAll()
+                .ToList();
 
             // 获取目标 DbSet
             var targetDbSet = targetContext.Set<T>();
@@ -57,7 +80,124 @@ namespace UniformMaterialManagementSystem.Utils
 
             // 添加到目标数据库
             targetDbSet.AddRange(sourceData);
-            targetContext.SaveChanges();
+            await targetContext.SaveChangesAsync();
+        }
+
+        private static void CreateExportFolder()
+        {
+            if (!Directory.Exists(DataBasePath))
+            {
+                Directory.CreateDirectory(DataBasePath);
+            }
+        }
+
+        public static IQueryable<TEntity> IncludeAll<TEntity>(this DbSet<TEntity> dbSet, int maxDepth = int.MaxValue) where TEntity :class
+        {
+            IQueryable<TEntity> result = dbSet;
+            var context = dbSet.GetService<ICurrentDbContext>().Context;
+            var includePaths = GetIncludePaths<TEntity>(context, maxDepth);
+
+            foreach (var includePath in includePaths)
+            {
+                result = result.Include(includePath);
+            }
+
+            return result;
+        }
+
+        private static IEnumerable<string> GetIncludePaths<T>(DbContext context, int maxDepth = int.MaxValue)
+        {
+            if (maxDepth < 0)
+                throw new ArgumentOutOfRangeException(nameof(maxDepth));
+
+            var entityType = context.Model.FindEntityType(typeof(T));
+            var includedNavigations = new HashSet<INavigation>();
+            var stack = new Stack<IEnumerator<INavigation>>();
+
+            while (true)
+            {
+                var entityNavigations = new List<INavigation>();
+
+                if (stack.Count <= maxDepth)
+                {
+                    if (entityType != null)
+                        foreach (var navigation in entityType.GetNavigations())
+                        {
+                            if (includedNavigations.Add(navigation))
+                                entityNavigations.Add(navigation);
+                        }
+                }
+
+                if (entityNavigations.Count == 0)
+                {
+                    if (stack.Count > 0)
+                        yield return string.Join(".", stack.Reverse().Select(e => e.Current.Name));
+                }
+                else
+                {
+                    foreach (var navigation in entityNavigations)
+                    {
+                        var inverseNavigation = navigation.Inverse;
+                        if (inverseNavigation != null)
+                            includedNavigations.Add(inverseNavigation);
+                    }
+
+                    stack.Push(entityNavigations.GetEnumerator());
+                }
+
+                while (stack.Count > 0 && !stack.Peek().MoveNext())
+                    stack.Pop();
+
+                if (stack.Count == 0)
+                    break;
+
+                entityType = stack.Peek().Current.TargetEntityType;
+            }
+        }
+
+        private static void EncryptFile(string inputFile, string outputFile)
+        {
+            // 生成密钥和初始化向量
+            GenerateAesKeyAndIv(out var key, out var iv);
+
+            using var aesAlg = Aes.Create();
+            aesAlg.Key = key;
+            aesAlg.IV = iv;
+
+            var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
+
+            using var outFileStream = new FileStream(outputFile, FileMode.Create);
+            using var csEncrypt = new CryptoStream(outFileStream, encryptor, CryptoStreamMode.Write);
+            using var inFileStream = new FileStream(inputFile, FileMode.Open);
+
+            inFileStream.CopyTo(csEncrypt);
+        }
+
+        private static void DecryptFile(string inputFile, string outputFile)
+        {
+            // 生成密钥和初始化向量
+            GenerateAesKeyAndIv(out var key, out var iv);
+
+            using var aesAlg = Aes.Create();
+            aesAlg.Key = key;
+            aesAlg.IV = iv;
+
+            var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
+
+            using var fileStream = new FileStream(inputFile, FileMode.Open);
+            using var csDecrypt = new CryptoStream(fileStream, decryptor, CryptoStreamMode.Read);
+            using var outFileStream = new FileStream(outputFile, FileMode.Create);
+
+            csDecrypt.CopyTo(outFileStream);
+        }
+
+        private static void GenerateAesKeyAndIv(out byte[] key, out byte[] iv)
+        {
+            using var pdb = new Rfc2898DeriveBytes(Password, [0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
+            ]);
+
+            key = pdb.GetBytes(32); // 256位密钥
+            iv = pdb.GetBytes(16); // 128位IV
         }
     }
 }

+ 3 - 0
UniformMaterialManagementSystem/ViewModels/LoginPageViewModel.cs

@@ -51,6 +51,9 @@ namespace UniformMaterialManagementSystem.ViewModels
         [RelayCommand]
         private void Login(Window loginWindow)
         {
+            // todo 测试使用
+            //DataBaseUtil.ExportTable<User>("C:\\Users\\wangbc\\Desktop\\text.db");
+
             // 验证所有属性
             ValidateAllProperties();
 

+ 6 - 6
UniformMaterialManagementSystem/ViewModels/RolePageViewModel.cs

@@ -202,12 +202,12 @@ namespace UniformMaterialManagementSystem.ViewModels
             if (state != EntityState.Detached)  //新增行
             {
                 //查询菜单项
-                using (SqliteContext context = new SqliteContext())
-                {
-                    var roles = context.Roles.Include(r => r.RoleMenus)
-                        .ThenInclude(rm => rm.MenuItem).Include(ro => ro.Menus).ToList();
-                    roleMenu = roles.First(r => r.Guid == role.Guid);
-                }
+                //using (SqliteContext context = new SqliteContext())
+                //{
+                //    var roles = context.Roles.Include(r => r.RoleMenus)
+                //        .ThenInclude(rm => rm.MenuItem).Include(ro => ro.Menus).ToList();
+                //    roleMenu = roles.First(r => r.Guid == role.Guid);
+                //}
             }
 
             //获取当前行的菜单权限

+ 2 - 2
UniformMaterialManagementSystem/Views/SampleRegistrationPage.xaml.cs

@@ -89,8 +89,8 @@ namespace UniformMaterialManagementSystem.Views
             SampleRegistrationModel? preSampleRegistration = e.RemovedItems[0] as SampleRegistrationModel;
             if (preSampleRegistration == null) return;
 
-            using SqliteContext context = new();
-            var sampleRegistration = context.SampleRegistrations.Where(x => x.Guid == preSampleRegistration.Guid).ToList().FirstOrDefault();
+            //using SqliteContext context = new();
+            //var sampleRegistration = context.SampleRegistrations.Where(x => x.Guid == preSampleRegistration.Guid).ToList().FirstOrDefault();
             //if (sampleRegistration == null)//新增行
             //{
             //    MessageBox.Show("数据已新增,请保存后切换行!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);