Skip to content

Commit a6b099c

Browse files
committed
重构字典类型的数据组装器,以更加类型确定性的方式获取记录字段值。
注:TDengine 时序库的数据记录的 GetValue(..) 方法在处理 VarChar 类型时,返回的是字符字节数组,所以必须通过对应的 GetString(..) 方法才能确保被正确识别。
1 parent 7d3acd6 commit a6b099c

File tree

2 files changed

+49
-17
lines changed

2 files changed

+49
-17
lines changed

Zongsoft.Data/src/Common/DictionaryPopulator.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Authors:
1010
* 钟峰(Popeye Zhong) <zongsoft@qq.com>
1111
*
12-
* Copyright (C) 2010-2020 Zongsoft Studio <http://www.zongsoft.com>
12+
* Copyright (C) 2010-2026 Zongsoft Studio <http://www.zongsoft.com>
1313
*
1414
* This file is part of Zongsoft.Data library.
1515
*
@@ -32,41 +32,50 @@
3232
using System.Collections;
3333
using System.Collections.Generic;
3434

35+
using Zongsoft.Data.Metadata;
36+
3537
namespace Zongsoft.Data.Common;
3638

3739
public class DictionaryPopulator : IDataPopulator
3840
{
3941
#region 成员字段
40-
private readonly Type _type;
41-
private readonly string[] _keys;
4242
private readonly Func<int, IDictionary> _creator;
43+
private readonly IDataEntityProperty[] _properties;
4344
#endregion
4445

4546
#region 构造函数
46-
internal protected DictionaryPopulator(Type type, string[] keys)
47+
internal protected DictionaryPopulator(Type type, IDataEntityProperty[] properties)
4748
{
48-
_type = type ?? throw new ArgumentNullException(nameof(type));
49-
_keys = keys ?? throw new ArgumentNullException(nameof(keys));
49+
_properties = properties ?? throw new ArgumentNullException(nameof(properties));
5050
_creator = this.GetCreator(type);
5151
}
5252
#endregion
5353

5454
#region 公共方法
5555
public T Populate<T>(IDataRecord record)
5656
{
57-
if(record.FieldCount != _keys.Length)
57+
if(record.FieldCount != _properties.Length)
5858
throw new DataException("The record of populate has failed.");
5959

6060
//创建一个对应的实体字典
6161
var dictionary = _creator(record.FieldCount);
6262

6363
for(var i = 0; i < record.FieldCount; i++)
6464
{
65-
if(!record.IsDBNull(i))
66-
dictionary[_keys[i]] = record.GetValue(i);
65+
if(record.IsDBNull(i))
66+
continue;
67+
68+
var property = _properties[i];
69+
if(property == null)
70+
continue;
71+
72+
dictionary[property.Name] = GetValue(record, property, i, false);
6773
}
6874

6975
return dictionary.Count > 0 ? (T)dictionary : default;
76+
77+
static object GetValue(IDataRecord record, IDataEntityProperty property, int ordinal, bool nullable) =>
78+
property.IsSimplex(out var simplex) ? record.GetValue(ordinal, simplex.Type.DbType, nullable) : null;
7079
}
7180
#endregion
7281

Zongsoft.Data/src/Common/DictionaryPopulatorProvider.cs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,45 @@ private DictionaryPopulatorProvider() { }
4343
#endregion
4444

4545
#region 公共方法
46-
public bool CanPopulate(Type type)
47-
{
48-
return Zongsoft.Common.TypeExtension.IsDictionary(type);
49-
}
50-
46+
public bool CanPopulate(Type type) => Zongsoft.Common.TypeExtension.IsDictionary(type);
5147
public IDataPopulator GetPopulator(IDataDriver driver, Type type, IDataRecord record, Metadata.IDataEntity entity = null)
5248
{
53-
var keys = new string[record.FieldCount];
49+
var properties = new Metadata.IDataEntityProperty[record.FieldCount];
5450

5551
for(int i = 0; i < record.FieldCount; i++)
5652
{
5753
//获取字段名对应的属性名(注意:由查询引擎确保返回的记录列名就是属性名)
58-
keys[i] = record.GetName(i);
54+
properties[i] = GetProperty(entity, record.GetName(i));
55+
}
56+
57+
return new DictionaryPopulator(type, properties);
58+
}
59+
#endregion
60+
61+
#region 私有方法
62+
private Metadata.IDataEntityProperty GetProperty(Metadata.IDataEntity entity, string path)
63+
{
64+
if(entity.Properties.TryGetValue(path, out var property))
65+
return property;
66+
67+
var parts = path.Split('.');
68+
69+
if(parts.Length > 1)
70+
{
71+
for(int i = 0; i < parts.Length; i++)
72+
{
73+
if(entity == null || !entity.Properties.TryGetValue(parts[i], out property))
74+
return null;
75+
76+
if(property is Metadata.IDataEntityComplexProperty complex)
77+
entity = complex.Foreign;
78+
else
79+
entity = null;
80+
}
5981
}
6082

61-
return new DictionaryPopulator(type, keys);
83+
//确保属性地址指向的最终属性不能是导航属性
84+
return property == null || property.IsComplex ? null : property;
6285
}
6386
#endregion
6487
}

0 commit comments

Comments
 (0)