|
@@ -1,9 +1,8 @@
|
|
|
-using System.Collections;
|
|
|
-using Microsoft.Data.Sqlite;
|
|
|
+using Microsoft.Data.Sqlite;
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
using Microsoft.Win32;
|
|
|
|
|
|
-using System.Collections.ObjectModel;
|
|
|
+using System.Collections;
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
|
using System.IO;
|
|
@@ -49,6 +48,12 @@ namespace UniformMaterialManagementSystem.Utils
|
|
|
|
|
|
if (isExecMigrate)
|
|
|
{
|
|
|
+ // 检查是否存在文件,存在则删除
|
|
|
+ if (File.Exists(SourcePath))
|
|
|
+ {
|
|
|
+ File.Delete(SourcePath);
|
|
|
+ }
|
|
|
+
|
|
|
var optionsBuilderSource = new DbContextOptionsBuilder<SqliteContext>();
|
|
|
optionsBuilderSource.UseSqlite($"Data Source={SourcePath}");
|
|
|
|
|
@@ -103,85 +108,89 @@ namespace UniformMaterialManagementSystem.Utils
|
|
|
}
|
|
|
|
|
|
connection.Close();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static string ImportData()
|
|
|
+ {
|
|
|
+ // 创建 OpenFileDialog 实例
|
|
|
+ var openFileDialog = new OpenFileDialog
|
|
|
+ {
|
|
|
+ // 配置对话框属性
|
|
|
+ Filter = "数据包(*.db)|*.db", // 设置文件筛选器
|
|
|
+ Title = "打开数据包" // 设置对话框标题
|
|
|
+ };
|
|
|
+
|
|
|
+ var sourcePath = string.Empty;
|
|
|
+
|
|
|
+ // 显示对话框并检查用户是否选择了文件
|
|
|
+ if (openFileDialog.ShowDialog() == true)
|
|
|
+ {
|
|
|
+ // 获取选中的文件路径
|
|
|
+ sourcePath = openFileDialog.FileName;
|
|
|
+ }
|
|
|
+
|
|
|
+ CreateExportFolder();
|
|
|
|
|
|
+ // 检查是否存在文件,存在则删除
|
|
|
+ if (File.Exists(SourcePath))
|
|
|
+ {
|
|
|
+ File.Delete(SourcePath);
|
|
|
+ }
|
|
|
+
|
|
|
+ DecryptFile(sourcePath, SourcePath);
|
|
|
+
|
|
|
+ return sourcePath;
|
|
|
}
|
|
|
|
|
|
- public static async Task ImportData<T>(SqliteContext context, IEnumerable<T> entities) where T : class
|
|
|
+ public static async Task ImportTable<T>(SqliteContext context, string tableName, IEnumerable<T> sourceData) where T : class?
|
|
|
{
|
|
|
- var dbSet = context.Set<T>();
|
|
|
+ await using var connection = new SqliteConnection("Data Source=UniformMaterialManagementSystem.db");
|
|
|
+ connection.Open();
|
|
|
|
|
|
- foreach (var entity in entities)
|
|
|
+ List<T> updateList = [];
|
|
|
+ List<T> insertList = [];
|
|
|
+
|
|
|
+ // 检查数据是否存在
|
|
|
+ var enumerable = sourceData as T[] ?? sourceData.ToArray();
|
|
|
+ foreach (var data in enumerable)
|
|
|
{
|
|
|
- var entry = context.Entry(entity);
|
|
|
- var primaryKey = entry.Metadata.FindPrimaryKey();
|
|
|
+ if (data == null) { continue; }
|
|
|
+
|
|
|
+ var (sql, parameters) = ExistsSql(data, tableName);
|
|
|
+ await using var command = new SqliteCommand(sql, connection);
|
|
|
+ command.Parameters.AddRange(parameters.ToArray());
|
|
|
+ var result = command.ExecuteScalar();
|
|
|
+ var isExist = Convert.ToInt32(result) > 0;
|
|
|
|
|
|
- if (primaryKey != null)
|
|
|
+ if (isExist)
|
|
|
{
|
|
|
- var keyValues = primaryKey.Properties.Select(p => p.GetGetter().GetClrValue(entity)).ToArray();
|
|
|
- var existingEntity = await dbSet.FindAsync(keyValues);
|
|
|
-
|
|
|
- if (existingEntity != null)
|
|
|
- {
|
|
|
- // 实体已存在,更新它
|
|
|
- context.Entry(existingEntity).CurrentValues.SetValues(entity);
|
|
|
-
|
|
|
- // 更新导航属性
|
|
|
- foreach (var navigation in entry.Navigations)
|
|
|
- {
|
|
|
- if (navigation.Metadata.IsCollection)
|
|
|
- {
|
|
|
- // 处理集合导航属性
|
|
|
- var collectionEntry = context.Entry(existingEntity).Collection(navigation.Metadata.Name);
|
|
|
- await collectionEntry.LoadAsync();
|
|
|
-
|
|
|
- if (collectionEntry.CurrentValue is ObservableCollection<object> existingCollection && navigation.CurrentValue is ObservableCollection<object> newCollection)
|
|
|
- {
|
|
|
-
|
|
|
- //foreach (var item in newCollection.ToList())
|
|
|
- //{
|
|
|
- // if (!existingCollection.Contains(item))
|
|
|
- // {
|
|
|
- // collectionEntry.Add(item);
|
|
|
- // }
|
|
|
- //}
|
|
|
-
|
|
|
- //foreach (var item in existingCollection.ToList())
|
|
|
- //{
|
|
|
- // if (!newCollection.Contains(item))
|
|
|
- // {
|
|
|
- // collectionEntry.Remove(item);
|
|
|
- // }
|
|
|
- //}
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // 处理引用导航属性
|
|
|
- var referenceEntry = context.Entry(existingEntity).Reference(navigation.Metadata.Name);
|
|
|
- await referenceEntry.LoadAsync();
|
|
|
- if (referenceEntry.CurrentValue == null)
|
|
|
- {
|
|
|
- referenceEntry.CurrentValue = navigation.CurrentValue;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (navigation.CurrentValue != null)
|
|
|
- {
|
|
|
- context.Entry(referenceEntry.CurrentValue).CurrentValues.SetValues(navigation.CurrentValue);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- // 实体不存在,添加它
|
|
|
- await dbSet.AddAsync(entity);
|
|
|
- }
|
|
|
+ updateList.Add(data);
|
|
|
}
|
|
|
+ else
|
|
|
+ {
|
|
|
+ insertList.Add(data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新数据
|
|
|
+ foreach (var data in updateList)
|
|
|
+ {
|
|
|
+ var (sql, parameters) = UpdateSql(data, tableName);
|
|
|
+ await using var command = new SqliteCommand(sql, connection);
|
|
|
+ command.Parameters.AddRange(parameters.ToArray());
|
|
|
+ command.ExecuteNonQuery();
|
|
|
}
|
|
|
|
|
|
- await context.SaveChangesAsync();
|
|
|
+ // 插入数据
|
|
|
+ foreach (var data in insertList)
|
|
|
+ {
|
|
|
+ var (sql, parameters) = InsertSql(data, tableName);
|
|
|
+ await using var command = new SqliteCommand(sql, connection);
|
|
|
+ command.Parameters.AddRange(parameters.ToArray());
|
|
|
+ command.ExecuteNonQuery();
|
|
|
+ }
|
|
|
+
|
|
|
+ connection.Close();
|
|
|
}
|
|
|
|
|
|
private static void CreateExportFolder()
|
|
@@ -203,11 +212,19 @@ namespace UniformMaterialManagementSystem.Utils
|
|
|
|
|
|
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);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ 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, FileAccess.Read, FileShare.ReadWrite);
|
|
|
|
|
|
- inFileStream.CopyTo(csEncrypt);
|
|
|
+ inFileStream.CopyTo(csEncrypt);
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ Console.WriteLine(e);
|
|
|
+ throw;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private static void DecryptFile(string inputFile, string outputFile)
|
|
@@ -221,11 +238,19 @@ namespace UniformMaterialManagementSystem.Utils
|
|
|
|
|
|
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);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ using var fileStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
|
|
+ using var csDecrypt = new CryptoStream(fileStream, decryptor, CryptoStreamMode.Read);
|
|
|
+ using var outFileStream = new FileStream(outputFile, FileMode.Create);
|
|
|
|
|
|
- csDecrypt.CopyTo(outFileStream);
|
|
|
+ csDecrypt.CopyTo(outFileStream);
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ Console.WriteLine(e);
|
|
|
+ throw;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private static void GenerateAesKeyAndIv(out byte[] key, out byte[] iv)
|
|
@@ -292,7 +317,6 @@ namespace UniformMaterialManagementSystem.Utils
|
|
|
|
|
|
public static (string sql, List<SqliteParameter> parameters) DeleteSql<T>(T entity, string tableName) where T : class?
|
|
|
{
|
|
|
- var type = typeof(T);
|
|
|
var primaryKeyProps = GetPrimaryKeyProperties<T>();
|
|
|
var whereClause = string.Join(" AND ", primaryKeyProps.Select(p => $"{p.Name} = @{p.Name}"));
|
|
|
|