Skip to content

Commit

Permalink
优化对象拷贝;优化CsvDb搜索
Browse files Browse the repository at this point in the history
  • Loading branch information
nnhy committed Apr 26, 2024
1 parent 0cbd3ef commit caf2962
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 29 deletions.
29 changes: 18 additions & 11 deletions NewLife.Core/IO/CsvDb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,32 +172,32 @@ private Boolean Set(T model, Boolean add)
{
if (Comparer == null) throw new ArgumentNullException(nameof(Comparer));

return FindAll(e => Comparer.Equals(model, e), 1).FirstOrDefault();
return Query(e => Comparer.Equals(model, e), 1).FirstOrDefault();
}

/// <summary>获取满足条件的第一行数据</summary>
/// <param name="predicate"></param>
/// <returns></returns>
public T? Find(Func<T, Boolean>? predicate) => FindAll(predicate, 1).FirstOrDefault();
public T? Find(Func<T, Boolean>? predicate) => Query(predicate, 1).FirstOrDefault();

/// <summary>获取所有数据行</summary>
/// <returns></returns>
public IList<T> FindAll() => FindAll(null);
public IList<T> FindAll() => Query(null).ToList();

/// <summary>获取满足条件的数据行,性能好,顺序查找</summary>
/// <param name="predicate"></param>
/// <param name="count"></param>
/// <returns></returns>
public IList<T> FindAll(Func<T, Boolean>? predicate, Int32 count = -1)
public IEnumerable<T> Query(Func<T, Boolean>? predicate, Int32 count = -1)
{
var file = GetFile();
if (!File.Exists(file)) return new List<T>();
if (!File.Exists(file)) yield break;

lock (this)
{
using var csv = new CsvFile(file, false) { Encoding = Encoding };

var list = new List<T>();
//var list = new List<T>();
var headers = new Dictionary<String, Int32>();
var pis = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
while (true)
Expand All @@ -217,10 +217,11 @@ public IList<T> FindAll(Func<T, Boolean>? predicate, Int32 count = -1)
}
else
{
var flag = false;
var model = new T();
try
{
// 反射构建对象
var model = new T();
foreach (var pi in pis)
{
var name = SerialHelper.GetName(pi);
Expand All @@ -235,20 +236,26 @@ public IList<T> FindAll(Func<T, Boolean>? predicate, Int32 count = -1)

if (predicate == null || predicate(model))
{
list.Add(model);

if (--count == 0) break;
//list.Add(model);
flag = true;
}
}
catch (Exception ex)
{
// 读取某一行出错,放弃该行
XTrace.WriteException(ex);
continue;
}

if (!flag) continue;

yield return model;

if (--count == 0) break;
}
}

return list;
//return list;
}
}

Expand Down
25 changes: 8 additions & 17 deletions NewLife.Core/Reflection/IReflect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Web.Script.Serialization;
using System.Xml.Serialization;
using NewLife.Data;
using static System.Collections.Specialized.BitVector32;

namespace NewLife.Reflection;

Expand Down Expand Up @@ -544,6 +543,7 @@ private IList<PropertyInfo> GetProperties2(Type type, Boolean baseFirst)
#endregion

#region 对象拷贝
private static Dictionary<Type, IDictionary<String, PropertyInfo>> _properties = [];
/// <summary>从源对象拷贝数据到目标对象</summary>
/// <param name="target">目标对象</param>
/// <param name="source">源对象</param>
Expand All @@ -557,38 +557,33 @@ public virtual void Copy(Object target, Object source, Boolean deep = false, par
// 基础类型无法拷贝
if (targetType.IsBaseType()) throw new XException("The base type {0} cannot be copied", targetType.FullName);

var sourceType = source.GetType();
if (!_properties.TryGetValue(sourceType, out var sourceProperties))
_properties[sourceType] = sourceProperties = sourceType.GetProperties(true).ToDictionary(e => e.Name, e => e);

// 不是深度拷贝时,直接复制引用
if (!deep)
{
var sourceType = source.GetType();

// 借助 IModel 优化取值赋值,有 IExtend 扩展属性的实体类过于复杂而不支持,例如IEntity就有脏数据问题
if (target is IModel dst && target is not IExtend)
{
var pis = sourceType.GetProperties(true);
foreach (var pi in targetType.GetProperties(true))
{
if (!pi.CanWrite) continue;
if (excludes != null && excludes.Contains(pi.Name)) continue;

var pi2 = pis.FirstOrDefault(e => e.Name == pi.Name);
if (pi2 != null && pi2.CanRead)
if (sourceProperties.TryGetValue(pi.Name, out var pi2) && pi2.CanRead)
dst[pi.Name] = source is IModel src ? src[pi2.Name] : GetValue(source, pi2);
}
}
else
{
var pis = sourceType.GetProperties(true);
foreach (var pi in targetType.GetProperties(true))
{
if (!pi.CanWrite) continue;
if (excludes != null && excludes.Contains(pi.Name)) continue;
//if (pi.GetIndexParameters().Length > 0) continue;
//if (pi.GetCustomAttribute<IgnoreDataMemberAttribute>(false) != null) continue;
//if (pi.GetCustomAttribute<XmlIgnoreAttribute>() != null) continue;

var pi2 = pis.FirstOrDefault(e => e.Name == pi.Name);
if (pi2 != null && pi2.CanRead)
if (sourceProperties.TryGetValue(pi.Name, out var pi2) && pi2.CanRead)
SetValue(target, pi, source is IModel src ? src[pi2.Name] : GetValue(source, pi2));
}
}
Expand All @@ -597,12 +592,10 @@ public virtual void Copy(Object target, Object source, Boolean deep = false, par

// 来源对象转为字典
var dic = new Dictionary<String, Object?>();
foreach (var pi in source.GetType().GetProperties(true))
foreach (var pi in sourceProperties.Values)
{
if (!pi.CanRead) continue;
if (excludes != null && excludes.Contains(pi.Name)) continue;
//if (pi.GetIndexParameters().Length > 0) continue;
//if (pi.GetCustomAttribute<XmlIgnoreAttribute>() != null) continue;

dic[pi.Name] = GetValue(source, pi);
}
Expand All @@ -621,8 +614,6 @@ public virtual void Copy(Object target, IDictionary<String, Object?> source, Boo
foreach (var pi in target.GetType().GetProperties(true))
{
if (!pi.CanWrite) continue;
//if (pi.GetIndexParameters().Length > 0) continue;
//if (pi.GetCustomAttribute<XmlIgnoreAttribute>() != null) continue;

if (source.TryGetValue(pi.Name, out var obj))
{
Expand Down
2 changes: 1 addition & 1 deletion XUnitTest.Core/IO/CsvDbTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public void GetAllTest()
}

// 高级查找
var list3 = db.FindAll(e => e.Code is >= 100 and < 1000);
var list3 = db.Query(e => e.Code is >= 100 and < 1000);
var list4 = list.Where(e => e.Code is >= 100 and < 1000).ToList();
Assert.Equal(list4.Select(e => e.Code), list3.Select(e => e.Code));
}
Expand Down

0 comments on commit caf2962

Please sign in to comment.