2 // Mono.Data.TdsClient.TdsDataReader.cs
5 // Rodrigo Moya (rodrigo@ximian.com)
6 // Daniel Morgan (danmorg@sc.rr.com)
7 // Tim Coleman (tim@timcoleman.com)
9 // (C) Ximian, Inc 2002
10 // (C) Daniel Morgan 2002
11 // Copyright (C) Tim Coleman, 2002
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using Mono.Data.TdsTypes;
36 using Mono.Data.Tds.Protocol;
38 using System.Collections;
39 using System.ComponentModel;
41 using System.Data.Common;
43 namespace Mono.Data.TdsClient {
44 public sealed class TdsDataReader : MarshalByRefObject, IEnumerable, IDataReader, IDisposable, IDataRecord
49 ArrayList dataTypeNames;
50 bool disposed = false;
57 DataTable schemaTable;
63 internal TdsDataReader (TdsCommand command)
65 this.command = command;
66 schemaTable = ConstructSchemaTable ();
70 isSelect = (command.CommandText.Trim ().ToUpper ().StartsWith ("SELECT"));
71 command.Tds.RecordsAffected = 0;
75 #endregion // Constructors
83 public int FieldCount {
84 get { return fieldCount; }
87 public bool IsClosed {
88 get { return isClosed; }
91 public object this [int i] {
92 get { return GetValue (i); }
95 public object this [string name] {
96 get { return GetValue (GetOrdinal (name)); }
99 public int RecordsAffected {
104 return command.Tds.RecordsAffected;
108 #endregion // Properties
115 command.CloseDataReader (moreResults);
118 private static DataTable ConstructSchemaTable ()
120 Type booleanType = Type.GetType ("System.Boolean");
121 Type stringType = Type.GetType ("System.String");
122 Type intType = Type.GetType ("System.Int32");
123 Type typeType = Type.GetType ("System.Type");
124 Type shortType = Type.GetType ("System.Int16");
126 DataTable schemaTable = new DataTable ("SchemaTable");
127 schemaTable.Columns.Add ("ColumnName", stringType);
128 schemaTable.Columns.Add ("ColumnOrdinal", intType);
129 schemaTable.Columns.Add ("ColumnSize", intType);
130 schemaTable.Columns.Add ("NumericPrecision", shortType);
131 schemaTable.Columns.Add ("NumericScale", shortType);
132 schemaTable.Columns.Add ("IsUnique", booleanType);
133 schemaTable.Columns.Add ("IsKey", booleanType);
134 schemaTable.Columns.Add ("BaseServerName", stringType);
135 schemaTable.Columns.Add ("BaseCatalogName", stringType);
136 schemaTable.Columns.Add ("BaseColumnName", stringType);
137 schemaTable.Columns.Add ("BaseSchemaName", stringType);
138 schemaTable.Columns.Add ("BaseTableName", stringType);
139 schemaTable.Columns.Add ("DataType", typeType);
140 schemaTable.Columns.Add ("AllowDBNull", booleanType);
141 schemaTable.Columns.Add ("ProviderType", intType);
142 schemaTable.Columns.Add ("IsAliased", booleanType);
143 schemaTable.Columns.Add ("IsExpression", booleanType);
144 schemaTable.Columns.Add ("IsIdentity", booleanType);
145 schemaTable.Columns.Add ("IsAutoIncrement", booleanType);
146 schemaTable.Columns.Add ("IsRowVersion", booleanType);
147 schemaTable.Columns.Add ("IsHidden", booleanType);
148 schemaTable.Columns.Add ("IsLong", booleanType);
149 schemaTable.Columns.Add ("IsReadOnly", booleanType);
154 private void Dispose (bool disposing)
158 schemaTable.Dispose ();
165 public bool GetBoolean (int i)
167 object value = GetValue (i);
168 if (!(value is bool)) {
169 if (value is DBNull) throw new TdsNullValueException ();
170 throw new InvalidCastException ();
175 public byte GetByte (int i)
177 object value = GetValue (i);
178 if (!(value is byte)) {
179 if (value is DBNull) throw new TdsNullValueException ();
180 throw new InvalidCastException ();
185 public long GetBytes (int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
187 object value = GetValue (i);
188 if (!(value is byte [])) {
189 if (value is DBNull) throw new TdsNullValueException ();
190 throw new InvalidCastException ();
192 Array.Copy ((byte []) value, (int) dataIndex, buffer, bufferIndex, length);
193 return ((byte []) value).Length - dataIndex;
196 public char GetChar (int i)
198 object value = GetValue (i);
199 if (!(value is char)) {
200 if (value is DBNull) throw new TdsNullValueException ();
201 throw new InvalidCastException ();
206 public long GetChars (int i, long dataIndex, char[] buffer, int bufferIndex, int length)
208 object value = GetValue (i);
209 if (!(value is char[])) {
210 if (value is DBNull) throw new TdsNullValueException ();
211 throw new InvalidCastException ();
213 Array.Copy ((char []) value, (int) dataIndex, buffer, bufferIndex, length);
214 return ((char []) value).Length - dataIndex;
217 [MonoTODO ("Implement GetData")]
218 public IDataReader GetData (int i)
220 throw new NotImplementedException ();
223 public string GetDataTypeName (int i)
225 return (string) dataTypeNames [i];
228 public DateTime GetDateTime (int i)
230 object value = GetValue (i);
231 if (!(value is DateTime)) {
232 if (value is DBNull) throw new TdsNullValueException ();
233 throw new InvalidCastException ();
235 return (DateTime) value;
238 public decimal GetDecimal (int i)
240 object value = GetValue (i);
241 if (!(value is decimal)) {
242 if (value is DBNull) throw new TdsNullValueException ();
243 throw new InvalidCastException ();
245 return (decimal) value;
248 public double GetDouble (int i)
250 object value = GetValue (i);
251 if (!(value is double)) {
252 if (value is DBNull) throw new TdsNullValueException ();
253 throw new InvalidCastException ();
255 return (double) value;
258 public Type GetFieldType (int i)
260 return (Type) schemaTable.Rows[i]["DataType"];
263 public float GetFloat (int i)
265 object value = GetValue (i);
266 if (!(value is float)) {
267 if (value is DBNull) throw new TdsNullValueException ();
268 throw new InvalidCastException ();
270 return (float) value;
273 public Guid GetGuid (int i)
275 object value = GetValue (i);
276 if (!(value is Guid)) {
277 if (value is DBNull) throw new TdsNullValueException ();
278 throw new InvalidCastException ();
283 public short GetInt16 (int i)
285 object value = GetValue (i);
286 if (!(value is short)) {
287 if (value is DBNull) throw new TdsNullValueException ();
288 throw new InvalidCastException ();
290 return (short) value;
293 public int GetInt32 (int i)
295 object value = GetValue (i);
296 if (!(value is int)) {
297 if (value is DBNull) throw new TdsNullValueException ();
298 throw new InvalidCastException ();
303 public long GetInt64 (int i)
305 object value = GetValue (i);
306 if (!(value is long)) {
307 if (value is DBNull) throw new TdsNullValueException ();
308 throw new InvalidCastException ();
313 public string GetName (int i)
315 return (string) schemaTable.Rows[i]["ColumnName"];
318 public int GetOrdinal (string name)
320 foreach (DataRow schemaRow in schemaTable.Rows)
321 if (((string) schemaRow ["ColumnName"]).Equals (name))
322 return (int) schemaRow ["ColumnOrdinal"];
323 foreach (DataRow schemaRow in schemaTable.Rows)
324 if (String.Compare (((string) schemaRow ["ColumnName"]), name, true) == 0)
325 return (int) schemaRow ["ColumnOrdinal"];
326 throw new IndexOutOfRangeException ();
329 public DataTable GetSchemaTable ()
331 if (schemaTable.Rows != null && schemaTable.Rows.Count > 0)
339 dataTypeNames = new ArrayList ();
341 foreach (TdsDataColumn schema in command.Tds.Columns) {
342 DataRow row = schemaTable.NewRow ();
345 row ["ColumnName"] = GetSchemaValue (schema.ColumnName);
346 row ["ColumnSize"] = GetSchemaValue (schema.ColumnSize);
347 row ["ColumnOrdinal"] = GetSchemaValue (schema.ColumnOrdinal);
348 row ["NumericPrecision"] = GetSchemaValue (schema.NumericPrecision);
349 row ["NumericScale"] = GetSchemaValue (schema.NumericScale);
350 row ["IsUnique"] = GetSchemaValue (schema.IsUnique);
351 row ["IsKey"] = GetSchemaValue (schema.IsKey);
352 row ["IsAliased"] = GetSchemaValue (schema.IsAliased);
353 row ["IsExpression"] = GetSchemaValue (schema.IsExpression);
354 row ["IsIdentity"] = GetSchemaValue (schema.IsIdentity);
355 row ["IsAutoIncrement"] = GetSchemaValue (schema.IsAutoIncrement);
356 row ["IsRowVersion"] = GetSchemaValue (schema.IsRowVersion);
357 row ["IsHidden"] = GetSchemaValue (schema.IsHidden);
358 row ["IsReadOnly"] = GetSchemaValue (schema.IsReadOnly);
359 row ["BaseServerName"] = GetSchemaValue (schema.BaseServerName);
360 row ["BaseCatalogName"] = GetSchemaValue (schema.BaseCatalogName);
361 row ["BaseColumnName"] = GetSchemaValue (schema.BaseColumnName);
362 row ["BaseSchemaName"] = GetSchemaValue (schema.BaseSchemaName);
363 row ["BaseTableName"] = GetSchemaValue (schema.BaseTableName);
364 row ["AllowDBNull"] = GetSchemaValue (schema.AllowDBNull);
366 row ["ColumnName"] = GetSchemaValue (schema, "ColumnName");
367 row ["ColumnSize"] = GetSchemaValue (schema, "ColumnSize");
368 row ["ColumnOrdinal"] = GetSchemaValue (schema, "ColumnOrdinal");
369 row ["NumericPrecision"] = GetSchemaValue (schema, "NumericPrecision");
370 row ["NumericScale"] = GetSchemaValue (schema, "NumericScale");
371 row ["IsUnique"] = GetSchemaValue (schema, "IsUnique");
372 row ["IsKey"] = GetSchemaValue (schema, "IsKey");
373 row ["IsAliased"] = GetSchemaValue (schema, "IsAliased");
374 row ["IsExpression"] = GetSchemaValue (schema, "IsExpression");
375 row ["IsIdentity"] = GetSchemaValue (schema, "IsIdentity");
376 row ["IsAutoIncrement"] = GetSchemaValue (schema, "IsAutoIncrement");
377 row ["IsRowVersion"] = GetSchemaValue (schema, "IsRowVersion");
378 row ["IsHidden"] = GetSchemaValue (schema, "IsHidden");
379 row ["IsReadOnly"] = GetSchemaValue (schema, "IsReadOnly");
380 row ["BaseServerName"] = GetSchemaValue (schema, "BaseServerName");
381 row ["BaseCatalogName"] = GetSchemaValue (schema, "BaseCatalogName");
382 row ["BaseColumnName"] = GetSchemaValue (schema, "BaseColumnName");
383 row ["BaseSchemaName"] = GetSchemaValue (schema, "BaseSchemaName");
384 row ["BaseTableName"] = GetSchemaValue (schema, "BaseTableName");
385 row ["AllowDBNull"] = GetSchemaValue (schema, "AllowDBNull");
388 // We don't always get the base column name.
389 if (row ["BaseColumnName"] == DBNull.Value)
390 row ["BaseColumnName"] = row ["ColumnName"];
392 switch ((TdsColumnType) schema ["ColumnType"]) {
393 case TdsColumnType.Image :
394 dataTypeNames.Add ("image");
395 row ["ProviderType"] = (int) TdsType.Image;
396 row ["DataType"] = typeof (byte[]);
397 row ["IsLong"] = true;
399 case TdsColumnType.Text :
400 dataTypeNames.Add ("text");
401 row ["ProviderType"] = (int) TdsType.Text;
402 row ["DataType"] = typeof (string);
403 row ["IsLong"] = true;
405 case TdsColumnType.UniqueIdentifier :
406 dataTypeNames.Add ("uniqueidentifier");
407 row ["ProviderType"] = (int) TdsType.UniqueIdentifier;
408 row ["DataType"] = typeof (Guid);
409 row ["IsLong"] = false;
411 case TdsColumnType.VarBinary :
412 case TdsColumnType.BigVarBinary :
413 dataTypeNames.Add ("varbinary");
414 row ["ProviderType"] = (int) TdsType.VarBinary;
415 row ["DataType"] = typeof (byte[]);
416 row ["IsLong"] = true;
418 case TdsColumnType.IntN :
419 case TdsColumnType.Int4 :
420 dataTypeNames.Add ("int");
421 row ["ProviderType"] = (int) TdsType.Int;
422 row ["DataType"] = typeof (int);
423 row ["IsLong"] = false;
425 case TdsColumnType.VarChar :
426 case TdsColumnType.BigVarChar :
427 dataTypeNames.Add ("varchar");
428 row ["ProviderType"] = (int) TdsType.VarChar;
429 row ["DataType"] = typeof (string);
430 row ["IsLong"] = false;
432 case TdsColumnType.Binary :
433 case TdsColumnType.BigBinary :
434 dataTypeNames.Add ("binary");
435 row ["ProviderType"] = (int) TdsType.Binary;
436 row ["DataType"] = typeof (byte[]);
437 row ["IsLong"] = true;
439 case TdsColumnType.Char :
440 case TdsColumnType.BigChar :
441 dataTypeNames.Add ("char");
442 row ["ProviderType"] = (int) TdsType.Char;
443 row ["DataType"] = typeof (string);
444 row ["IsLong"] = false;
446 case TdsColumnType.Int1 :
447 dataTypeNames.Add ("tinyint");
448 row ["ProviderType"] = (int) TdsType.TinyInt;
449 row ["DataType"] = typeof (byte);
450 row ["IsLong"] = false;
452 case TdsColumnType.Bit :
453 case TdsColumnType.BitN :
454 dataTypeNames.Add ("bit");
455 row ["ProviderType"] = (int) TdsType.Bit;
456 row ["DataType"] = typeof (bool);
457 row ["IsLong"] = false;
459 case TdsColumnType.Int2 :
460 dataTypeNames.Add ("smallint");
461 row ["ProviderType"] = (int) TdsType.SmallInt;
462 row ["DataType"] = typeof (short);
463 row ["IsLong"] = false;
465 case TdsColumnType.DateTime4 :
466 case TdsColumnType.DateTime :
467 case TdsColumnType.DateTimeN :
468 dataTypeNames.Add ("datetime");
469 row ["ProviderType"] = (int) TdsType.DateTime;
470 row ["DataType"] = typeof (DateTime);
471 row ["IsLong"] = false;
473 case TdsColumnType.Real :
474 dataTypeNames.Add ("real");
475 row ["ProviderType"] = (int) TdsType.Real;
476 row ["DataType"] = typeof (float);
478 case TdsColumnType.Money :
479 case TdsColumnType.MoneyN :
480 case TdsColumnType.Money4 :
481 dataTypeNames.Add ("money");
482 row ["ProviderType"] = (int) TdsType.Money;
483 row ["DataType"] = typeof (decimal);
484 row ["IsLong"] = false;
486 case TdsColumnType.Float8 :
487 case TdsColumnType.FloatN :
488 dataTypeNames.Add ("float");
489 row ["ProviderType"] = (int) TdsType.Float;
490 row ["DataType"] = typeof (double);
491 row ["IsLong"] = false;
493 case TdsColumnType.NText :
494 dataTypeNames.Add ("ntext");
495 row ["ProviderType"] = (int) TdsType.NText;
496 row ["DataType"] = typeof (string);
497 row ["IsLong"] = true;
499 case TdsColumnType.NVarChar :
500 dataTypeNames.Add ("nvarchar");
501 row ["ProviderType"] = (int) TdsType.NVarChar;
502 row ["DataType"] = typeof (string);
503 row ["IsLong"] = false;
505 case TdsColumnType.Decimal :
506 case TdsColumnType.Numeric :
507 dataTypeNames.Add ("decimal");
508 row ["ProviderType"] = (int) TdsType.Decimal;
509 row ["DataType"] = typeof (decimal);
510 row ["IsLong"] = false;
512 case TdsColumnType.NChar :
513 dataTypeNames.Add ("nchar");
514 row ["ProviderType"] = (int) TdsType.NChar;
515 row ["DataType"] = typeof (string);
516 row ["IsLong"] = false;
518 case TdsColumnType.SmallMoney :
519 dataTypeNames.Add ("smallmoney");
520 row ["ProviderType"] = (int) TdsType.SmallMoney;
521 row ["DataType"] = typeof (decimal);
522 row ["IsLong"] = false;
525 dataTypeNames.Add ("variant");
526 row ["ProviderType"] = (int) TdsType.Variant;
527 row ["DataType"] = typeof (object);
528 row ["IsLong"] = false;
532 schemaTable.Rows.Add (row);
539 private static object GetSchemaValue (TdsDataColumn schema, string key)
541 object ret = schema [key];
549 static object GetSchemaValue (object value)
557 public TdsBinary GetTdsBinary (int i)
559 throw new NotImplementedException ();
562 public TdsBoolean GetTdsBoolean (int i)
564 object value = GetTdsValue (i);
565 if (!(value is TdsBoolean))
566 throw new InvalidCastException ();
567 return (TdsBoolean) value;
570 public TdsByte GetTdsByte (int i)
572 object value = GetTdsValue (i);
573 if (!(value is TdsByte))
574 throw new InvalidCastException ();
575 return (TdsByte) value;
578 public TdsDateTime GetTdsDateTime (int i)
580 object value = GetTdsValue (i);
581 if (!(value is TdsDateTime))
582 throw new InvalidCastException ();
583 return (TdsDateTime) value;
586 public TdsDecimal GetTdsDecimal (int i)
588 object value = GetTdsValue (i);
589 if (!(value is TdsDecimal))
590 throw new InvalidCastException ();
591 return (TdsDecimal) value;
594 public TdsDouble GetTdsDouble (int i)
596 object value = GetTdsValue (i);
597 if (!(value is TdsDouble))
598 throw new InvalidCastException ();
599 return (TdsDouble) value;
602 public TdsGuid GetTdsGuid (int i)
604 object value = GetTdsValue (i);
605 if (!(value is TdsGuid))
606 throw new InvalidCastException ();
607 return (TdsGuid) value;
610 public TdsInt16 GetTdsInt16 (int i)
612 object value = GetTdsValue (i);
613 if (!(value is TdsInt16))
614 throw new InvalidCastException ();
615 return (TdsInt16) value;
618 public TdsInt32 GetTdsInt32 (int i)
620 object value = GetTdsValue (i);
621 if (!(value is TdsInt32))
622 throw new InvalidCastException ();
623 return (TdsInt32) value;
626 public TdsInt64 GetTdsInt64 (int i)
628 object value = GetTdsValue (i);
629 if (!(value is TdsInt64))
630 throw new InvalidCastException ();
631 return (TdsInt64) value;
634 public TdsMoney GetTdsMoney (int i)
636 object value = GetTdsValue (i);
637 if (!(value is TdsMoney))
638 throw new InvalidCastException ();
639 return (TdsMoney) value;
642 public TdsSingle GetTdsSingle (int i)
644 object value = GetTdsValue (i);
645 if (!(value is TdsSingle))
646 throw new InvalidCastException ();
647 return (TdsSingle) value;
650 public TdsString GetTdsString (int i)
652 object value = GetTdsValue (i);
653 if (!(value is TdsString))
654 throw new InvalidCastException ();
655 return (TdsString) value;
658 [MonoTODO ("Implement TdsBigDecimal conversion. TdsType.Real fails tests?")]
659 public object GetTdsValue (int i)
661 TdsType type = (TdsType) (schemaTable.Rows [i]["ProviderType"]);
662 object value = GetValue (i);
666 if (value == DBNull.Value)
667 return TdsInt64.Null;
668 return (TdsInt64) ((long) value);
671 case TdsType.VarBinary:
672 case TdsType.Timestamp:
673 if (value == DBNull.Value)
674 return TdsBinary.Null;
675 return (TdsBinary) ((byte[]) value);
677 if (value == DBNull.Value)
678 return TdsBoolean.Null;
679 return (TdsBoolean) ((bool) value);
683 case TdsType.NVarChar:
685 case TdsType.VarChar:
686 if (value == DBNull.Value)
687 return TdsString.Null;
688 return (TdsString) ((string) value);
689 case TdsType.DateTime:
690 case TdsType.SmallDateTime:
691 if (value == DBNull.Value)
692 return TdsDateTime.Null;
693 return (TdsDateTime) ((DateTime) value);
694 case TdsType.Decimal:
695 if (value == DBNull.Value)
696 return TdsDecimal.Null;
697 if (value is TdsBigDecimal)
698 return TdsDecimal.FromTdsBigDecimal ((TdsBigDecimal) value);
699 return (TdsDecimal) ((decimal) value);
701 if (value == DBNull.Value)
702 return TdsDouble.Null;
703 return (TdsDouble) ((double) value);
705 if (value == DBNull.Value)
706 return TdsInt32.Null;
707 return (TdsInt32) ((int) value);
709 case TdsType.SmallMoney:
710 if (value == DBNull.Value)
711 return TdsMoney.Null;
712 return (TdsMoney) ((decimal) value);
714 if (value == DBNull.Value)
715 return TdsSingle.Null;
716 return (TdsSingle) ((float) value);
717 case TdsType.UniqueIdentifier:
718 if (value == DBNull.Value)
720 return (TdsGuid) ((Guid) value);
721 case TdsType.SmallInt:
722 if (value == DBNull.Value)
723 return TdsInt16.Null;
724 return (TdsInt16) ((short) value);
725 case TdsType.TinyInt:
726 if (value == DBNull.Value)
728 return (TdsByte) ((byte) value);
731 throw new InvalidOperationException ("The type of this column is unknown.");
734 public int GetTdsValues (object[] values)
737 int columnCount = schemaTable.Rows.Count;
738 int arrayCount = values.Length;
740 if (arrayCount > columnCount)
745 for (int i = 0; i < count; i += 1)
746 values [i] = GetTdsValue (i);
751 public string GetString (int i)
753 object value = GetValue (i);
754 if (!(value is string)) {
755 if (value is DBNull) throw new TdsNullValueException ();
756 throw new InvalidCastException ();
758 return (string) value;
761 public object GetValue (int i)
763 return command.Tds.ColumnValues [i];
766 public int GetValues (object[] values)
768 int len = values.Length;
769 int bigDecimalIndex = command.Tds.ColumnValues.BigDecimalIndex;
771 // If a four-byte decimal is stored, then we can't convert to
772 // a native type. Throw an OverflowException.
773 if (bigDecimalIndex >= 0 && bigDecimalIndex < len)
774 throw new OverflowException ();
776 command.Tds.ColumnValues.CopyTo (0, values, 0, len);
777 return (len > FieldCount ? len : FieldCount);
780 void IDisposable.Dispose ()
783 GC.SuppressFinalize (this);
786 IEnumerator IEnumerable.GetEnumerator ()
788 return new DbEnumerator (this);
791 public bool IsDBNull (int i)
793 return GetValue (i) == DBNull.Value;
796 public bool NextResult ()
798 if ((command.CommandBehavior & CommandBehavior.SingleResult) != 0 && resultsRead > 0)
800 if (command.Tds.DoneProc)
803 schemaTable.Rows.Clear ();
805 moreResults = command.Tds.NextResult ();
815 if ((command.CommandBehavior & CommandBehavior.SingleRow) != 0 && rowsRead > 0)
817 if ((command.CommandBehavior & CommandBehavior.SchemaOnly) != 0)
822 bool result = command.Tds.NextRow ();
829 #endregion // Methods