01.Blogs :
MNF  

Fill Dataset with rows in a specified range from ADODB.Recordset

I've used Index Server using MSIDXS(Microsoft® OLE DB Provider for Indexing Service ) to query LAN documents from  ASP.NET, but on the big catalogs it is quite slow. In  a few places it's noted, that MSIDXS is significally slower than IXSSO. So I decided to try IXSSO and found an article on ASP101.The article limits the number returned using Q.MaxRecords = 250 for performance reasons.
However if you want to show how many total records satisfied your search  it's not a good idea to limit the number of returned records.
If I didn't specified MaxRecords, I found that using 
IXSSO with DataAdapter.Fill is not quicker than MSIDXS.
 Further investigation showed that in the following two lines of code:
Dim rs As Object = Q.CreateRecordset("nonsequential")
da.Fill(ds, rs, sTableName)
to fill ADO.NET dataset takes 20 times more time than to CreateRecordset for my big catalog(rs.RecordCount=65000).
Because the application actually shows only one page per time, I wanted to use Fill overload to refreshes rows in a specified range  but there is no public overload for ADO Recordset.
(Using Reflector I found that there are private methods in System.Data.OleDb namespace but unfortunately it isn't possible  to use them externally)
It is essential to use "nonsequential" parameter of CreateRecordset, because it returns back valid rs.RecordCount.(As a test I've tried to pass "sequential", but then I had to to calculate total count of records manually, which is very slow.)

So I had to create function that copies to the DataTable only specified range(see the code below).

 /// <summary>
        ///  Fill -Copies table only page section
        /// </summary>
        /// <param name="dataTable">New Table to be created.</param>
        
public static int Fill(DataSet ds,string TableName, ADODB.Recordset rs, int startRecord,    int maxRecords
)
        {
            
DataTable table = new DataTable( TableName
);
            
int fieldCount = BuildSchemaTable( table,  rs
);
            
table.BeginLoadData
();
            
object[] values = new object[fieldCount
];
            
int nCount=0
;
            while (
0 < startRecord)
//skip before start
            
{
                if (
rs.EOF
)
                {
                    return
nCount
;
                }
                
rs.MoveNext
();
                
startRecord
--;
                
nCount
++;
            }
            
int num1 = 0
;
            if (
0 < maxRecords
)
            {
                while ((
num1 < maxRecords) && !rs.EOF
)
                {
                    
RecordsetToArray(rs,values
);
                    
table.LoadDataRow(values, true
);
                    
rs.MoveNext
();
                    
num1
++;
                }
                
//return num1;
            
}
            
nCount+=num1

            table.EndLoadData();
            
ds.Tables.Add(table
);
            return
nCount
;
        }
        
protected  static int  BuildSchemaTable(DataTable table, ADODB.Recordset rs
)
        {
            
int fieldCount = rs.Fields.Count
;
            for (
int i = 0; i < fieldCount; i
++)
            {
//Convert ADODB.DataTypeEnum to System.Type
                
table.Columns.Add(rs.Fields[i].Name , FromAdoDbType(rs.Fields[i].Type
));
            }
            return
fieldCount
;
        }
        
protected  static void RecordsetToArray(ADODB.Recordset rs,object[] values
)
        {
            
Debug.Assert(values.Length>=rs.Fields.Count
);
            for (
int i=0;i<rs.Fields.Count;i
++)
            {
                
values[i]=rs.Fields[i].Value
;
            }
        }
        
public  static System.Type  FromAdoDbType(ADODB.DataTypeEnum AdoDbType
)
        {
            
//Based on ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconadotypemappingtonetframeworktype.htm
            
switch (AdoDbType
)
            {
                case
ADODB.DataTypeEnum.adEmpty
:
                {
                    return
null
;
                }
                case
ADODB.DataTypeEnum.adBoolean
:
                {
                    return
typeof
(Boolean);
                }
                case
ADODB.DataTypeEnum.adTinyInt
:
                {
                    return
typeof(SByte
);
                }
                case
ADODB.DataTypeEnum.adSingle
:
                {
                    return
typeof(Single
);
                }
                case
ADODB.DataTypeEnum.adSmallInt:case ADODB.DataTypeEnum.adUnsignedTinyInt:
// promoted to Int16
                
{
                    return
typeof(Int16
);
                }
                case
ADODB.DataTypeEnum.adInteger:case ADODB.DataTypeEnum.adUnsignedSmallInt:
// promoted to Int32
                
{
                    return
typeof(Int32
);
                }
                case
ADODB.DataTypeEnum.adBigInt:case ADODB.DataTypeEnum.adUnsignedInt:
// promoted to Int64
                
{
                    return
typeof(Int64
);
                }
                    
//
                
case ADODB.DataTypeEnum.adCurrency:case ADODB.DataTypeEnum.adDecimal:case ADODB.DataTypeEnum.adNumeric
:
                case
ADODB.DataTypeEnum.adUnsignedBigInt:
//adUnsignedBigInt promoted to Decimal
                
{
                    return
typeof(Decimal
);
                }
                case
ADODB.DataTypeEnum.adDate:case ADODB.DataTypeEnum.adDBDate:case ADODB.DataTypeEnum.adDBTime
:
                case
ADODB.DataTypeEnum.adDBTimeStamp:case ADODB.DataTypeEnum.adFileTime
:
                {
                    return
typeof(DateTime
);
                }
                case
ADODB.DataTypeEnum.adGUID
:
                {
                    return
typeof(Guid
);
                }
                case
ADODB.DataTypeEnum.adError
:
                {
                    return
typeof(System.Runtime.InteropServices.ExternalException
);
                }
                case
ADODB.DataTypeEnum.adIUnknown:case ADODB.DataTypeEnum.adIDispatch:case ADODB.DataTypeEnum.adVariant
:
                case
ADODB.DataTypeEnum.adPropVariant
:
                {
                    return
typeof
(object);
                }

                case
ADODB.DataTypeEnum.adChar:case ADODB.DataTypeEnum.adWChar:case ADODB.DataTypeEnum.adBSTR
:
                case
ADODB.DataTypeEnum.adVarWChar
:
                {
                    return
typeof
(String);
                }
            } 


 

posted on Monday, May 09, 2005 1:43 AM by MNF

# COM CleanUp when using IXSSO in .Net @ Thursday, September 22, 2005 8:56 PM

Michael Freidgeim


 
03.UPDATE CALENDAR :
<May 2005>
SunMonTueWedThuFriSat
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

05.MY LINKS :

07.Subscriptions :

Subscriptions


© Copyright 2005 Microsoft Corporation. All Rights Reserved.
Terms of Use | Privacy Statement | Code of Conduct | Hosted by MaximumASP for Microsoft
WHO-BAR