1
1
using System ;
2
+ using System . Data . Common ;
3
+ using System . Linq ;
4
+ using NHibernate . Engine ;
5
+ using NHibernate . Id . Insert ;
6
+ using NHibernate . Persister . Collection ;
7
+ using NHibernate . Persister . Entity ;
2
8
using NHibernate . SqlCommand ;
3
9
using NHibernate . Type ;
4
10
@@ -9,22 +15,65 @@ internal static class PostInsertIdentityPersisterExtension
9
15
{
10
16
public static SqlString GetSelectByUniqueKeyString (
11
17
this IPostInsertIdentityPersister persister ,
12
- string [ ] propertyNames )
18
+ string [ ] suppliedPropertyNames ,
19
+ out IType [ ] parameterTypes )
13
20
{
14
21
if ( persister is ICompositeKeyPostInsertIdentityPersister multiProperties )
15
- return multiProperties . GetSelectByUniqueKeyString ( propertyNames ) ;
22
+ return multiProperties . GetSelectByUniqueKeyString ( suppliedPropertyNames , out parameterTypes ) ;
16
23
17
- if ( propertyNames . Length > 1 )
24
+ if ( suppliedPropertyNames . Length > 1 )
18
25
{
19
26
throw new IdentifierGenerationException (
20
27
$ "persister { persister } does not implement { nameof ( ICompositeKeyPostInsertIdentityPersister ) } , " +
21
28
$ "which is required for selecting by an unique key spanning multiple properties.") ;
22
29
}
23
30
31
+ if ( persister is IEntityPersister entityPersister )
32
+ {
33
+ var uniqueKeyPropertyNames = suppliedPropertyNames ?? DetermineNameOfPropertiesToUse ( entityPersister ) ;
34
+
35
+ parameterTypes = uniqueKeyPropertyNames . Select ( p => entityPersister . GetPropertyType ( p ) ) . ToArray ( ) ;
36
+ }
37
+ else if ( persister is IQueryableCollection collectionPersister )
38
+ {
39
+ parameterTypes = new [ ] { collectionPersister . KeyType , collectionPersister . ElementType } ;
40
+ }
41
+ else
42
+ {
43
+ throw new IdentifierGenerationException (
44
+ $ "Persister type { persister . GetType ( ) } is not supported by post insert identity persisters") ;
45
+ }
24
46
#pragma warning disable 618
25
- return persister . GetSelectByUniqueKeyString ( propertyNames [ 0 ] ) ;
47
+ return persister . GetSelectByUniqueKeyString ( suppliedPropertyNames [ 0 ] ) ;
26
48
#pragma warning restore 618
27
49
}
50
+
51
+ internal static string [ ] DetermineNameOfPropertiesToUse ( IEntityPersister persister )
52
+ {
53
+ var naturalIdPropertyIndices = persister . NaturalIdentifierProperties ;
54
+ if ( naturalIdPropertyIndices == null )
55
+ {
56
+ throw new IdentifierGenerationException (
57
+ "no natural-id property defined; need to specify [key] in generator parameters" ) ;
58
+ }
59
+
60
+ foreach ( var naturalIdPropertyIndex in naturalIdPropertyIndices )
61
+ {
62
+ var inclusion = persister . PropertyInsertGenerationInclusions [ naturalIdPropertyIndex ] ;
63
+ if ( inclusion != ValueInclusion . None )
64
+ {
65
+ throw new IdentifierGenerationException (
66
+ "natural-id also defined as insert-generated; need to specify [key] in generator parameters" ) ;
67
+ }
68
+ }
69
+
70
+ var result = new string [ naturalIdPropertyIndices . Length ] ;
71
+ for ( var i = 0 ; i < naturalIdPropertyIndices . Length ; i ++ )
72
+ {
73
+ result [ i ] = persister . PropertyNames [ naturalIdPropertyIndices [ i ] ] ;
74
+ }
75
+ return result ;
76
+ }
28
77
}
29
78
30
79
/// <summary>
@@ -56,7 +105,7 @@ public interface IPostInsertIdentityPersister
56
105
/// </param>
57
106
/// <returns> The SQL select string </returns>
58
107
// Since 5.2
59
- [ Obsolete ( "Have the persister implement IMultiPropertiesPostInsertIdentityPersister and use its GetSelectByUniqueKeyString(string[] propertyNames )." ) ]
108
+ [ Obsolete ( "Have the persister implement IMultiPropertiesPostInsertIdentityPersister and use its GetSelectByUniqueKeyString(string[] suppliedPropertyNames, out IType[] parameterTypes )." ) ]
60
109
SqlString GetSelectByUniqueKeyString ( string propertyName ) ;
61
110
62
111
#region NH specific
@@ -74,17 +123,36 @@ public interface IPostInsertIdentityPersister
74
123
/// An <see cref="IPostInsertIdentityPersister" /> that supports selecting by an unique key spanning
75
124
/// multiple properties.
76
125
/// </summary>
77
- public interface ICompositeKeyPostInsertIdentityPersister
126
+ public partial interface ICompositeKeyPostInsertIdentityPersister
78
127
{
79
128
/// <summary>
80
- /// Get a SQL select string that performs a select based on a unique
81
- /// key determined by the given array of property names.
129
+ /// Get a SQL select string that performs a select based on an unique key, optionnaly determined by
130
+ /// the given array of property names.
82
131
/// </summary>
83
- /// <param name="propertyNames">
84
- /// The names of the properties which map to the
85
- /// column(s) to use in the select statement restriction.
86
- /// </param>
132
+ /// <param name="suppliedPropertyNames">The names of the properties which map to the column(s) to use
133
+ /// in the select statement restriction. If supplied, they override the persister logic for determining
134
+ /// them.</param>
135
+ /// <param name="parameterTypes">In return, the parameter types used by the select string.< /param>
87
136
/// <returns>The SQL select string.</returns>
88
- SqlString GetSelectByUniqueKeyString ( string [ ] propertyNames ) ;
137
+ /// <exception cref="NotSupportedException">thrown if <paramref name="suppliedPropertyNames"/> are
138
+ /// specified on a persister which does not allow a custom key.</exception>
139
+ SqlString GetSelectByUniqueKeyString ( string [ ] suppliedPropertyNames , out IType [ ] parameterTypes ) ;
140
+
141
+ /// <summary>
142
+ /// Bind the parameter values of a SQL select command that performs a select based on an unique key.
143
+ /// </summary>
144
+ /// <param name="session">The current <see cref="ISession" />.</param>
145
+ /// <param name="selectCommand">The command.</param>
146
+ /// <param name="binder">The id insertion binder.</param>
147
+ /// <param name="suppliedPropertyNames">The names of the properties which map to the column(s) to use
148
+ /// in the select statement restriction. If supplied, they override the persister logic for determining
149
+ /// them.</param>
150
+ /// <exception cref="NotSupportedException">thrown if <paramref name="suppliedPropertyNames"/> are
151
+ /// specified on a persister which does not allow a custom key.</exception>
152
+ void BindSelectByUniqueKey (
153
+ ISessionImplementor session ,
154
+ DbCommand selectCommand ,
155
+ IBinder binder ,
156
+ string [ ] suppliedPropertyNames ) ;
89
157
}
90
158
}
0 commit comments