From 238ca5c36a6df09b199b020aeda8d3293cce2f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=BA=E8=83=BD=E5=A4=A7=E7=9F=B3=E5=A4=B4?= Date: Tue, 15 Jul 2025 15:16:24 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AE=9E=E4=BD=93=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E4=BA=8C=E8=BF=9B=E5=88=B6=E5=BA=8F=E5=88=97=E5=8C=96?= =?UTF-8?q?=E5=92=8CCsv=E8=AF=BB=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- XCode/Entity/EntityExtension.cs | 76 ++++++++++++++++++++------------- XCode/Membership/地区.Biz.cs | 2 +- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/XCode/Entity/EntityExtension.cs b/XCode/Entity/EntityExtension.cs index bbde82665..075e19733 100644 --- a/XCode/Entity/EntityExtension.cs +++ b/XCode/Entity/EntityExtension.cs @@ -1164,7 +1164,7 @@ public static class EntityExtension #endregion #region 读写数据流 - /// 转为DbTable + /// 实体列表转为DbTable /// 实体列表 /// public static DbTable ToTable(this IEnumerable list) where T : IEntity @@ -1204,7 +1204,7 @@ public static class EntityExtension return dt; } - /// 写入数据流 + /// 实体列表以二进制序列化写入数据流 /// 实体列表 /// 数据流 /// @@ -1212,6 +1212,7 @@ public static class EntityExtension { if (list == null) return 0; + //todo Binary需要字段记录已经写入多少字节,部分数据流不支持Position var bn = new Binary { Stream = stream, EncodeInt = true, FullTime = true }; var p = stream.Position; foreach (var entity in list) @@ -1285,9 +1286,7 @@ public static class EntityExtension if (list == null) return 0; var compressed = file.EndsWithIgnoreCase(".gz"); - return displayfields != null - ? file.AsFile().OpenWrite(compressed, fs => SaveCsv(list, fs, fields, displayfields)) - : file.AsFile().OpenWrite(compressed, fs => SaveCsv(list, fs, fields)); + return file.AsFile().OpenWrite(compressed, fs => SaveCsv(list, fs, fields, displayfields)); } /// 写入文件,Csv格式 @@ -1308,28 +1307,43 @@ public static class EntityExtension } - /// 从数据流读取列表 - /// 实体列表 + /// 从数据流读取实体列表 + /// 实体工厂 /// 数据流 /// 实体列表 - public static IEnumerable Read(this IList list, Stream stream) where T : IEntity + public static IEnumerable Read(this IEntityFactory factory, Stream stream) { - if (stream == null) yield break; + if (factory == null || stream == null) yield break; var bn = new Binary { Stream = stream, EncodeInt = true, FullTime = true }; - var fact = typeof(T).AsFactory(); while (stream.Position < stream.Length) { - var entity = (T)fact.Create(); + var entity = factory.Create(); if (entity is IAccessor acc) acc.Read(stream, bn); - list.Add(entity); - yield return entity; } } - /// 从文件读取列表,二进制格式 + /// 从文件读取实体列表,二进制格式 + /// 实体工厂 + /// 文件 + /// 实体列表 + public static IEnumerable LoadFile(this IEntityFactory factory, String file) + { + if (file.IsNullOrEmpty()) return []; + file = file.GetFullPath(); + if (!File.Exists(file)) return []; + + Stream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read); + + if (file.EndsWithIgnoreCase(".gz")) + fs = new GZipStream(fs, CompressionMode.Decompress); + + return Read(factory, fs); + } + + /// 从文件读取实体列表,二进制格式 /// 实体列表 /// 文件 /// 实体列表 @@ -1339,22 +1353,21 @@ public static class EntityExtension file = file.GetFullPath(); if (!File.Exists(file)) return list; - Stream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read); - var bn = new Binary { Stream = fs, EncodeInt = true, FullTime = true }; + var factory = typeof(T).AsFactory(); + foreach (var entity in factory.LoadFile(file)) + { + list.Add((T)entity); + } - if (file.EndsWithIgnoreCase(".gz")) - fs = new GZipStream(fs, CompressionMode.Decompress); - - return Read(list, fs).ToList(); + return list; } - /// 从数据流读取列表,Csv格式 - /// 实体列表 + /// 从数据流读取实体列表,Csv格式 + /// 实体工厂 /// 数据流 /// 实体列表 - public static IEnumerable LoadCsv(this IList list, Stream stream) where T : IEntity + public static IEnumerable LoadCsv(this IEntityFactory factory, Stream stream) { - var fact = typeof(T).AsFactory(); using var csv = new CsvFile(stream, true); // 匹配字段 @@ -1364,7 +1377,7 @@ public static class EntityExtension var fields = new FieldItem[names.Length]; for (var i = 0; i < names.Length; i++) { - fields[i] = fact.Fields.FirstOrDefault(e => names[i].EqualIgnoreCase(e.Name, e.DisplayName, e.ColumnName)); + fields[i] = factory.Fields.FirstOrDefault(e => names[i].EqualIgnoreCase(e.Name, e.DisplayName, e.ColumnName)); } // 读取数据 @@ -1373,15 +1386,13 @@ public static class EntityExtension var line = csv.ReadLine(); if (line == null || line.Length == 0) break; - var entity = (T)fact.Create(); + var entity = factory.Create(); for (var i = 0; i < fields.Length && i < line.Length; i++) { var fi = fields[i]; if (fi != null && !line[i].IsNullOrEmpty()) entity.SetItem(fi.Name, line[i].ChangeType(fi.Type)); } - list.Add(entity); - yield return entity; } } @@ -1397,7 +1408,14 @@ public static class EntityExtension if (!File.Exists(file)) return list; var compressed = file.EndsWithIgnoreCase(".gz"); - file.AsFile().OpenRead(compressed, fs => LoadCsv(list, fs).ToList()); + file.AsFile().OpenRead(compressed, fs => + { + var factory = typeof(T).AsFactory(); + foreach (var entity in factory.LoadCsv(fs)) + { + list.Add((T)entity); + } + }); return list; } diff --git a/XCode/Membership/地区.Biz.cs b/XCode/Membership/地区.Biz.cs index b4a9de988..9df88deb1 100644 --- a/XCode/Membership/地区.Biz.cs +++ b/XCode/Membership/地区.Biz.cs @@ -1150,7 +1150,7 @@ public partial class Area : Entity stream = new GZipStream(stream, CompressionMode.Decompress, true); stream = new BufferedStream(stream); } - list.LoadCsv(stream); + list = Meta.Factory.LoadCsv(stream).Cast().ToList(); } else list.LoadCsv(csvFile);