@@ -46,6 +46,8 @@ public class MongoCursorEnumerator<TDocument> : IEnumerator<TDocument>
4646 private int _replyIndex ;
4747 private ResponseFlags _responseFlags ;
4848 private long _openCursorId ;
49+ private ReadPreference _readPreference ;
50+ private QueryFlags _queryFlags ;
4951
5052 // constructors
5153 /// <summary>
@@ -206,8 +208,24 @@ private MongoConnection AcquireConnection()
206208 {
207209 if ( _serverInstance == null )
208210 {
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+
209227 // 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 ) ;
211229 _serverInstance = connection . ServerInstance ;
212230 return connection ;
213231 }
@@ -248,7 +266,7 @@ private MongoReplyMessage<TDocument> GetFirst()
248266 }
249267
250268 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 ) )
252270 {
253271 return GetReply ( connection , message ) ;
254272 }
@@ -331,15 +349,14 @@ private void KillCursor()
331349 private IMongoQuery WrapQuery ( )
332350 {
333351 BsonDocument formattedReadPreference = null ;
334- if ( _serverInstance . InstanceType == MongoServerInstanceType . ShardRouter )
352+ if ( _serverInstance . InstanceType == MongoServerInstanceType . ShardRouter
353+ && _readPreference . ReadPreferenceMode != ReadPreferenceMode . Primary )
335354 {
336- var readPreference = _cursor . ReadPreference ;
337-
338355 BsonArray tagSetsArray = null ;
339- if ( readPreference . ReadPreferenceMode != ReadPreferenceMode . Primary && readPreference . TagSets != null )
356+ if ( _readPreference . TagSets != null )
340357 {
341358 tagSetsArray = new BsonArray ( ) ;
342- foreach ( var tagSet in readPreference . TagSets )
359+ foreach ( var tagSet in _readPreference . TagSets )
343360 {
344361 var tagSetDocument = new BsonDocument ( ) ;
345362 foreach ( var tag in tagSet )
@@ -350,11 +367,14 @@ private IMongoQuery WrapQuery()
350367 }
351368 }
352369
353- formattedReadPreference = new BsonDocument
370+ if ( tagSetsArray != null || _readPreference . ReadPreferenceMode != ReadPreferenceMode . SecondaryPreferred )
354371 {
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+ }
358378 }
359379
360380 if ( _cursor . Options == null && formattedReadPreference == null )
0 commit comments