@@ -46,6 +46,8 @@ public class MongoCursorEnumerator<TDocument> : IEnumerator<TDocument>
46
46
private int _replyIndex ;
47
47
private ResponseFlags _responseFlags ;
48
48
private long _openCursorId ;
49
+ private ReadPreference _readPreference ;
50
+ private QueryFlags _queryFlags ;
49
51
50
52
// constructors
51
53
/// <summary>
@@ -206,8 +208,24 @@ private MongoConnection AcquireConnection()
206
208
{
207
209
if ( _serverInstance == null )
208
210
{
211
+ _readPreference = _cursor . ReadPreference ;
212
+ _queryFlags = _cursor . Flags ;
213
+ if ( _readPreference . ReadPreferenceMode != ReadPreferenceMode . Primary && _cursor . Collection . Name == "$cmd" )
214
+ {
215
+ var queryDocument = _cursor . Query . ToBsonDocument ( ) ;
216
+ var isSecondaryOk = MongoDefaults . CanCommandBeSentToSecondary ( queryDocument ) ;
217
+ if ( ! isSecondaryOk )
218
+ {
219
+ // if the command can't be sent to a secondary, then we use primary here
220
+ // regardless of the user's choice.
221
+ _readPreference = ReadPreference . Primary ;
222
+ // remove the slaveOk bit from the flags
223
+ _queryFlags &= ~ QueryFlags . SlaveOk ;
224
+ }
225
+ }
226
+
209
227
// first time we need a connection let Server.AcquireConnection pick the server instance
210
- var connection = _cursor . Server . AcquireConnection ( _cursor . Database , _cursor . ReadPreference ) ;
228
+ var connection = _cursor . Server . AcquireConnection ( _cursor . Database , _readPreference ) ;
211
229
_serverInstance = connection . ServerInstance ;
212
230
return connection ;
213
231
}
@@ -248,7 +266,7 @@ private MongoReplyMessage<TDocument> GetFirst()
248
266
}
249
267
250
268
var writerSettings = _cursor . Collection . GetWriterSettings ( connection ) ;
251
- using ( var message = new MongoQueryMessage ( writerSettings , _cursor . Collection . FullName , _cursor . Flags , _cursor . Skip , numberToReturn , WrapQuery ( ) , _cursor . Fields ) )
269
+ using ( var message = new MongoQueryMessage ( writerSettings , _cursor . Collection . FullName , _queryFlags , _cursor . Skip , numberToReturn , WrapQuery ( ) , _cursor . Fields ) )
252
270
{
253
271
return GetReply ( connection , message ) ;
254
272
}
@@ -331,15 +349,14 @@ private void KillCursor()
331
349
private IMongoQuery WrapQuery ( )
332
350
{
333
351
BsonDocument formattedReadPreference = null ;
334
- if ( _serverInstance . InstanceType == MongoServerInstanceType . ShardRouter )
352
+ if ( _serverInstance . InstanceType == MongoServerInstanceType . ShardRouter
353
+ && _readPreference . ReadPreferenceMode != ReadPreferenceMode . Primary )
335
354
{
336
- var readPreference = _cursor . ReadPreference ;
337
-
338
355
BsonArray tagSetsArray = null ;
339
- if ( readPreference . ReadPreferenceMode != ReadPreferenceMode . Primary && readPreference . TagSets != null )
356
+ if ( _readPreference . TagSets != null )
340
357
{
341
358
tagSetsArray = new BsonArray ( ) ;
342
- foreach ( var tagSet in readPreference . TagSets )
359
+ foreach ( var tagSet in _readPreference . TagSets )
343
360
{
344
361
var tagSetDocument = new BsonDocument ( ) ;
345
362
foreach ( var tag in tagSet )
@@ -350,11 +367,14 @@ private IMongoQuery WrapQuery()
350
367
}
351
368
}
352
369
353
- formattedReadPreference = new BsonDocument
370
+ if ( tagSetsArray != null || _readPreference . ReadPreferenceMode != ReadPreferenceMode . SecondaryPreferred )
354
371
{
355
- { "mode" , MongoUtils . ToCamelCase ( readPreference . ReadPreferenceMode . ToString ( ) ) } ,
356
- { "tags" , tagSetsArray , tagSetsArray != null } // optional
357
- } ;
372
+ formattedReadPreference = new BsonDocument
373
+ {
374
+ { "mode" , MongoUtils . ToCamelCase ( _readPreference . ReadPreferenceMode . ToString ( ) ) } ,
375
+ { "tags" , tagSetsArray , tagSetsArray != null } // optional
376
+ } ;
377
+ }
358
378
}
359
379
360
380
if ( _cursor . Options == null && formattedReadPreference == null )
0 commit comments