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);