1
1
using System ;
2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
- using System . Reflection ;
4
+ using System . Linq . Expressions ;
5
5
using System . Xml . Linq ;
6
6
using SolrNet . Impl ;
7
- using SolrNet . Mapping ;
7
+ using SolrNet . Linq . Expressions ;
8
8
9
9
namespace SolrNet . Linq . Impl
10
10
{
11
11
public class SelectResponseParser < TNew , TOld > : ISolrDocumentResponseParser < TNew >
12
12
{
13
- private readonly ConstructorInfo CtorInfo = typeof ( TNew ) . GetConstructors ( ) . Single ( ) ;
14
- private readonly ISolrFieldParser parser ;
13
+ private readonly ISolrDocumentResponseParser < TOld > _inner ;
14
+ private readonly ISolrDocumentResponseParser < Dictionary < string , object > > _dictionaryParser ;
15
+ private readonly MethodCallExpression _selectCall ;
16
+ private readonly SelectExpressionsCollection _selectState ;
15
17
16
- public SelectResponseParser ( ISolrFieldParser parser )
18
+ public SelectResponseParser ( ISolrDocumentResponseParser < TOld > inner , ISolrDocumentResponseParser < Dictionary < string , object > > dictionaryParser , MethodCallExpression selectCall , SelectExpressionsCollection selectState )
17
19
{
18
- this . parser = parser ?? throw new ArgumentNullException ( nameof ( parser ) ) ;
20
+ _inner = inner ?? throw new ArgumentNullException ( nameof ( inner ) ) ;
21
+ _dictionaryParser = dictionaryParser ?? throw new ArgumentNullException ( nameof ( dictionaryParser ) ) ;
22
+ _selectCall = selectCall ;
23
+ _selectState = selectState ;
19
24
}
20
-
21
25
public IList < TNew > ParseResults ( XElement parentNode )
22
26
{
23
- List < TNew > objList = new List < TNew > ( ) ;
24
27
if ( parentNode == null )
25
- return ( IList < TNew > ) objList ;
26
- foreach ( XElement element in parentNode . Elements ( ( XName ) "doc" ) )
27
- objList . Add ( this . ParseDocument ( element ) ) ;
28
- return ( IList < TNew > ) objList ;
28
+ return null ;
29
+
30
+ List < TNew > result = new List < TNew > ( ) ;
31
+ var docs = this . _dictionaryParser . ParseResults ( parentNode ) ;
32
+ IList < TOld > olds = this . _inner . ParseResults ( parentNode ) ;
33
+
34
+ for ( int i = 0 ; i < olds . Count ; i ++ )
35
+ {
36
+ result . Add ( this . GetResult ( olds [ i ] , docs [ i ] ) ) ;
37
+ }
38
+
39
+ return result ;
29
40
}
30
41
31
- public TNew ParseDocument ( XElement node )
42
+ private TNew GetResult ( TOld old , Dictionary < string , object > dictionary )
32
43
{
33
- Dictionary < string , XElement > fields = node . Elements ( ) . ToDictionary ( element => element . Attribute ( ( XName ) "name" ) . Value ) ;
34
-
35
- List < object > args = new List < object > ( fields . Count ) ;
36
- foreach ( ParameterInfo p in CtorInfo . GetParameters ( ) )
37
- {
38
- object obj = p . ParameterType . IsValueType ? Activator . CreateInstance ( p . ParameterType ) : null ;
39
- if ( fields . ContainsKey ( p . Name ) )
40
- {
41
- if ( p . ParameterType == typeof ( XElement ) )
42
- {
43
- string text = fields [ p . Name ] . ToString ( ) ;
44
- try
45
- {
46
-
47
- obj = XElement . Parse ( text ) ;
48
- }
49
- catch ( Exception e )
50
- {
51
- throw new InvalidOperationException (
52
- $ "Unable to set value for { p . Name } . Value { text } can't be parsed to XElement", e ) ;
53
- }
54
- }
55
- else if ( this . parser . CanHandleSolrType ( fields [ p . Name ] . Name . LocalName ) &&
56
- this . parser . CanHandleType ( p . ParameterType ) )
57
- {
58
- obj = this . parser . Parse ( fields [ p . Name ] , p . ParameterType ) ;
44
+ ReplaceCalculatedVisitor visitor = new ReplaceCalculatedVisitor ( this . _selectState , dictionary ) ;
59
45
60
- if ( obj != null )
61
- {
62
- if ( ! p . ParameterType . IsAssignableFrom ( obj . GetType ( ) ) )
63
- {
64
- throw new InvalidOperationException (
65
- $ "Unable to set value for { p . Name } . Value { obj } of type { obj . GetType ( ) } not assignable to type { p . ParameterType } ") ;
66
- }
67
- }
68
- else if ( p . ParameterType . IsValueType )
69
- {
70
- throw new InvalidOperationException (
71
- $ "Unable to set value for { p . Name } . Value null not assignable to type { p . ParameterType } ") ;
72
- }
73
- }
74
- }
46
+ LambdaExpression lambdaExpression = ( LambdaExpression ) this . _selectCall . Arguments [ 1 ] . StripQuotes ( ) ;
75
47
76
- args . Add ( obj ) ;
77
- }
48
+ LambdaExpression expression = ( LambdaExpression ) visitor . Visit ( lambdaExpression ) ;
49
+
50
+ object result = expression . Compile ( ) . DynamicInvoke ( old ) ;
78
51
79
- return ( TNew ) CtorInfo . Invoke ( args . ToArray ( ) ) ;
52
+ return ( TNew ) result ;
80
53
}
81
54
}
82
55
}
0 commit comments