3333using System . Threading . Tasks ;
3434using System . Reflection ;
3535
36+ using Zongsoft . Reflection ;
37+ using Zongsoft . Collections ;
38+
3639namespace Zongsoft . Data . Common ;
3740
3841public abstract class DataImporterBase : IDataImporter
@@ -50,49 +53,76 @@ public abstract class DataImporterBase : IDataImporter
5053 #region 私有方法
5154 private static MemberCollection GetMembers ( DataImportContext context )
5255 {
53- static MemberInfo GetMemberInfo ( Type type , string name )
54- {
55- if ( typeof ( System . Collections . IDictionary ) . IsAssignableFrom ( type ) )
56- {
57- var indexes = type . GetDefaultMembers ( ) ;
58- return indexes != null && indexes . Length > 0 ? indexes [ 0 ] : type . GetProperty ( "Item" , BindingFlags . Public | BindingFlags . Instance ) ;
59- }
56+ var members = new MemberCollection ( ) ;
6057
61- return ( MemberInfo ) type . GetProperty ( name , BindingFlags . Public | BindingFlags . Instance ) ??
62- ( MemberInfo ) type . GetField ( name , BindingFlags . Public | BindingFlags . Instance ) ;
63- }
58+ if ( typeof ( System . Collections . IDictionary ) . IsAssignableFrom ( context . ModelType ) )
59+ GenerateMembersWithoutInfo ( context , members ) ;
60+ else
61+ GenerateMembersWithInfo ( context , members ) ;
6462
65- var members = new MemberCollection ( ) ;
63+ return members ;
6664
67- if ( context . Members == null || context . Members . Length == 0 )
65+ static MemberInfo GetMemberInfo ( Type type , string name ) =>
66+ ( MemberInfo ) type . GetProperty ( name , BindingFlags . Public | BindingFlags . Instance ) ??
67+ ( MemberInfo ) type . GetField ( name , BindingFlags . Public | BindingFlags . Instance ) ;
68+
69+ static void GenerateMembersWithInfo ( DataImportContext context , MemberCollection members )
6870 {
69- foreach ( var property in context . Entity . Properties )
71+ if ( context . Members == null || context . Members . Length == 0 )
7072 {
71- if ( property . IsComplex )
72- continue ;
73+ foreach ( var property in context . Entity . Properties )
74+ {
75+ if ( property . IsComplex )
76+ continue ;
7377
74- var info = GetMemberInfo ( context . ModelType , property . Name ) ;
75- if ( info != null )
76- members . Add ( new Member ( context , info , ( Metadata . IDataEntitySimplexProperty ) property ) ) ;
78+ var info = GetMemberInfo ( context . ModelType , property . Name ) ;
79+ if ( info != null )
80+ members . Add ( new Member ( context , ( Metadata . IDataEntitySimplexProperty ) property , info ) ) ;
81+ }
82+ }
83+ else
84+ {
85+ for ( int i = 0 ; i < context . Members . Length ; i ++ )
86+ {
87+ if ( context . Entity . Properties . TryGetValue ( context . Members [ i ] , out var property ) )
88+ {
89+ if ( property . IsComplex )
90+ throw new DataException ( $ "The specified '{ property . Name } ' property cannot be a navigation property, only scalar field data can be import.") ;
91+
92+ var info = GetMemberInfo ( context . ModelType , property . Name ) ;
93+ if ( info != null )
94+ members . Add ( new Member ( context , ( Metadata . IDataEntitySimplexProperty ) property , info ) ) ;
95+ }
96+ }
7797 }
7898 }
79- else
99+
100+ static void GenerateMembersWithoutInfo ( DataImportContext context , MemberCollection members )
80101 {
81- for ( int i = 0 ; i < context . Members . Length ; i ++ )
102+ if ( context . Members == null || context . Members . Length == 0 )
82103 {
83- if ( context . Entity . Properties . TryGetValue ( context . Members [ i ] , out var property ) )
104+ foreach ( var property in context . Entity . Properties )
84105 {
85106 if ( property . IsComplex )
86- throw new DataException ( $ "The specified ' { property . Name } ' property cannot be a navigation property, only scalar field data can be import." ) ;
107+ continue ;
87108
88- var info = GetMemberInfo ( context . ModelType , property . Name ) ;
89- if ( info != null )
90- members . Add ( new Member ( context , info , ( Metadata . IDataEntitySimplexProperty ) property ) ) ;
109+ members . Add ( new Member ( context , ( Metadata . IDataEntitySimplexProperty ) property , null ) ) ;
91110 }
92111 }
93- }
112+ else
113+ {
114+ for ( int i = 0 ; i < context . Members . Length ; i ++ )
115+ {
116+ if ( context . Entity . Properties . TryGetValue ( context . Members [ i ] , out var property ) )
117+ {
118+ if ( property . IsComplex )
119+ throw new DataException ( $ "The specified '{ property . Name } ' property cannot be a navigation property, only scalar field data can be import.") ;
94120
95- return members ;
121+ members . Add ( new Member ( context , ( Metadata . IDataEntitySimplexProperty ) property , null ) ) ;
122+ }
123+ }
124+ }
125+ }
96126 }
97127 #endregion
98128
@@ -102,47 +132,43 @@ public readonly struct Member
102132 #region 私有变量
103133 private readonly DataImportContextBase _context ;
104134 private readonly IDataValidator _validator ;
105-
106- private readonly Reflection . FieldInfoExtension . Getter _fieldGetter ;
107- private readonly Reflection . FieldInfoExtension . Setter _fieldSetter ;
108- private readonly Reflection . PropertyInfoExtension . Getter _propertyGetter ;
109- private readonly Reflection . PropertyInfoExtension . Setter _propertySetter ;
110135 private readonly Delegate _getter ;
111136 private readonly Delegate _setter ;
112137 private readonly bool _isIndexer ;
113138 #endregion
114139
115140 #region 构造函数
116- public Member ( DataImportContextBase context , MemberInfo info , Metadata . IDataEntityProperty property )
141+ public Member ( DataImportContextBase context , Metadata . IDataEntityProperty property , MemberInfo member )
117142 {
118143 _context = context ?? throw new ArgumentNullException ( nameof ( context ) ) ;
119144 _validator = DataEnvironment . Validators . GetValidator ( context ) ;
120- this . Info = info ?? throw new ArgumentNullException ( nameof ( info ) ) ;
121145 this . Property = property ?? throw new ArgumentNullException ( nameof ( property ) ) ;
122146 this . Name = property . Name ;
123147
124- switch ( info )
148+ switch ( member )
125149 {
126150 case FieldInfo fieldInfo :
127- _fieldGetter = Reflection . FieldInfoExtension . GetGetter ( fieldInfo ) ;
128- _fieldSetter = Reflection . FieldInfoExtension . GetSetter ( fieldInfo ) ;
129- _getter = Reflection . FieldInfoExtension . GetGetter ( fieldInfo ) ;
130- _setter = Reflection . FieldInfoExtension . GetSetter ( fieldInfo ) ;
151+ this . Type = fieldInfo . FieldType ;
152+ _getter = fieldInfo . GetGetter ( ) ;
153+ _setter = fieldInfo . GetSetter ( ) ;
131154 break ;
132155 case PropertyInfo propertyInfo :
133- _propertyGetter = Reflection . PropertyInfoExtension . GetGetter ( propertyInfo ) ;
134- _propertySetter = Reflection . PropertyInfoExtension . GetSetter ( propertyInfo ) ;
135-
156+ this . Type = propertyInfo . PropertyType ;
157+ _getter = propertyInfo . GetGetter ( ) ;
158+ _setter = propertyInfo . GetSetter ( ) ;
159+ _isIndexer = propertyInfo . GetIndexParameters ( ) . Length > 0 ;
136160 break ;
137161 default :
138- throw new ArgumentException ( $ "The specified '{ info . Name } ' info is invalid member.") ;
162+ if ( member != null )
163+ throw new ArgumentException ( $ "The specified '{ member . Name } ' info is invalid member.") ;
164+ break ;
139165 }
140166 }
141167 #endregion
142168
143169 #region 公共字段
144170 public readonly string Name ;
145- public readonly MemberInfo Info ;
171+ public readonly Type Type ;
146172 public readonly Metadata . IDataEntityProperty Property ;
147173 #endregion
148174
@@ -170,13 +196,13 @@ public object GetValue(ref object target)
170196 if ( CanSequence ( property . Sequence ) )
171197 {
172198 //获取目标的当前属性值,如果获取失败或其值为空或数字零,则递增该字段序号
173- if ( ! this . TryGetValue ( ref target , out value ) || value == null || Convert . IsDBNull ( value ) || Zongsoft . Common . Convert . IsZero ( value ) )
199+ if ( ! this . TryGetMemberValue ( ref target , out value ) || value == null || Convert . IsDBNull ( value ) || Zongsoft . Common . Convert . IsZero ( value ) )
174200 {
175201 //递增当前属性对应的序号
176202 var id = _context . DataAccess . Sequencer . Increase ( property ) ;
177203
178204 //尝试将递增的序号值写入到目标对象的属性
179- this . TrySetValue ( ref target , type => Zongsoft . Common . Convert . ConvertValue ( id , type ) ) ;
205+ this . SetMemberValue ( ref target , Zongsoft . Common . Convert . ConvertValue ( id , this . Type ) ) ;
180206
181207 //返回最新的序号值
182208 return Convert . ChangeType ( id , property . Type . DbType . AsType ( ) ) ;
@@ -187,13 +213,13 @@ public object GetValue(ref object target)
187213 if ( _validator != null && _validator . OnImport ( _context , this . Property , out value ) )
188214 {
189215 //尝试验证器返回的值写入到目标对象的属性
190- this . TrySetValue ( ref target , value ) ;
216+ this . SetMemberValue ( ref target , value ) ;
191217
192218 //返回验证后的值
193219 return ConvertValue ( value , property . Type , property . Length , property . Nullable ) ;
194220 }
195221
196- if ( this . TryGetValue ( ref target , out value ) )
222+ if ( this . TryGetMemberValue ( ref target , out value ) )
197223 return ConvertValue ( value == null || value is string text && string . IsNullOrEmpty ( text ) ? property . DefaultValue : value , property . Type , property . Length , property . Nullable ) ;
198224 else
199225 return ConvertValue ( property . DefaultValue , property . Type , property . Length , property . Nullable ) ;
@@ -226,47 +252,32 @@ static bool IsString(DbType dbType) =>
226252 #endregion
227253
228254 #region 私有方法
229- private object GetFieldValue ( ref object target ) => ( ( Reflection . FieldInfoExtension . Getter ) _getter ) . Invoke ( ref target ) ;
230- private void SetFieldValue ( ref object target , object value ) => ( ( Reflection . FieldInfoExtension . Setter ) _setter ) . Invoke ( ref target , value ) ;
231- private object GetPropertyValue ( ref object target ) => ( ( Reflection . PropertyInfoExtension . Getter ) _getter ) . Invoke ( ref target ) ;
232-
233- private bool TryGetValue ( ref object target , out object value )
255+ private bool TryGetMemberValue ( ref object target , out object value )
234256 {
235- if ( this . Info is PropertyInfo property )
236- {
237- var parameters = property . GetIndexParameters ( ) ;
238- if ( parameters != null && parameters . Length == 1 && parameters [ 0 ] . ParameterType == typeof ( string ) )
239- return Reflection . Reflector . TryGetValue ( property , ref target , [ this . Name ] , out value ) ;
257+ if ( target is System . Collections . IDictionary dictionary )
258+ return dictionary . TryGetValue ( this . Name , out value ) ;
240259
241- var getter = Reflection . PropertyInfoExtension . GetGetter ( property ) ;
242- getter . Invoke ( ref target , this . Name ) ;
243- }
260+ if ( _getter is FieldInfoExtension . Getter getter )
261+ value = getter . Invoke ( ref target ) ;
244262
245- return Reflection . Reflector . TryGetValue ( this . Info , ref target , out value ) ;
246- }
263+ value = _isIndexer ?
264+ ( ( PropertyInfoExtension . Getter ) _getter ) . Invoke ( ref target , this . Name ) :
265+ ( ( PropertyInfoExtension . Getter ) _getter ) . Invoke ( ref target ) ;
247266
248- private bool TrySetValue ( ref object target , object value )
249- {
250- if ( this . Info is PropertyInfo property )
251- {
252- var parameters = property . GetIndexParameters ( ) ;
253- if ( parameters != null && parameters . Length == 1 && parameters [ 0 ] . ParameterType == typeof ( string ) )
254- return Reflection . Reflector . TrySetValue ( property , ref target , value , this . Name ) ;
255- }
256-
257- return Reflection . Reflector . TrySetValue ( this . Info , ref target , value ) ;
267+ return true ;
258268 }
259269
260- private bool TrySetValue ( ref object target , Func < Type , object > valueFactory )
270+ private void SetMemberValue ( ref object target , object value )
261271 {
262- if ( this . Info is PropertyInfo property )
263- {
264- var parameters = property . GetIndexParameters ( ) ;
265- if ( parameters != null && parameters . Length == 1 && parameters [ 0 ] . ParameterType == typeof ( string ) )
266- return Reflection . Reflector . TrySetValue ( property , ref target , valueFactory , this . Name ) ;
267- }
272+ if ( target is System . Collections . IDictionary dictionary )
273+ dictionary [ this . Name ] = value ;
268274
269- return Reflection . Reflector . TrySetValue ( this . Info , ref target , valueFactory ) ;
275+ if ( _setter is FieldInfoExtension . Setter setter )
276+ setter . Invoke ( ref target , value ) ;
277+ else if ( _isIndexer )
278+ ( ( PropertyInfoExtension . Setter ) _setter ) . Invoke ( ref target , value , this . Name ) ;
279+ else
280+ ( ( PropertyInfoExtension . Setter ) _setter ) . Invoke ( ref target , value ) ;
270281 }
271282
272283 [ System . Runtime . CompilerServices . MethodImpl ( System . Runtime . CompilerServices . MethodImplOptions . AggressiveInlining ) ]
0 commit comments