OpenLink Metadata Extensions for ADO.NET
- ADO.NET's Shortcomings as a Datasource-Independent API
- Plugging the Metadata Gaps
- Cross-Database Uniformity
- Building on ADO.NET 2.0 's Schema Support
- More Detailed Catalog Information
- More Detailed Data Source Information
- Metadata Support for ADO.NET 1.x
- Summary - Promoting Datasource Independence
ADO.NET's Shortcomings as a Datasource-Independent API
For all the strengths of ADO.NET, one of its major weaknesses is the lack of a rigid specification to which data providers must conform. ADO.NET differs markedly from some of its Microsoft forebears in this respect.
Unlike ADO.NET, the ODBC and OLE DB data access standards were built around rigid specifications detailing the functionality drivers must provide. Whilst the looseness of the ADO.NET specification might make it easier to write providers for data sources which don't fully conform to a rigid DBMS model and "lower the high bar" set by ODBC and OLE DB, the downside of this approach is that writing data source independent code becomes far more difficult. Indeed, one of the main reasons for the major success of ODBC and its ubiquity is its ability to allow developers to write database-agnostic applications.
ADO.NET 1.x is particularly weak at supporting provider independent code.
Although it is possible to exploit polymorphism and use instances of the System.Data.IDbxxx interfaces (e.g.
ADO.NET 2.0 goes some way towards addressing these most obvious shortcomings of ADO.NET 1.x.
The new To enhance the metadata available from ADO.NET, The metadata extensions build on the loose metadata support in ADO.NET 2.0 accessed through GetSchema returns a metadata collection in the form of a OpenLink UDA providers extend the above list to include: Columns, Of the 'non-standard' schemas supported by UDA providers, with the exception of As well as catalog information, another key requirement for creating deductive data-aware applications is knowledge of the capabilities and idiosyncrasies of the data source.
For instance, whether a database supports mixed case, uppercase or lowercase names for schema objects.
To aid writing data source independent code, this information should ideally be available in a standard form.
'Standard' ADO.NET 2.0 includes a An example In order to cater for cases where As well as extending the metadata support in ADO.NET 2.0, Where the .NET Framework v2 defines metadata related classes and enums for ADO.NET 2.0, which are missing in v1 of the Framework, the OpenLink are continuing their commitment to promoting database independent application development by actively addressing the considerable weaknesses of ADO.NET in this regard.
By extending the weak metadata support in ADO.NET to expose an ODBC-like metadata infrastructure across all their providers and all supported databases,
Plugging the Metadata Gaps
Cross-Database Uniformity
Building on ADO.NET 2.0 's Schema Support
More Detailed Catalog Information
<xs:element name="PrimaryKeys">
<xs:complexType>
<xs:sequence>
<xs:element name="TABLE_CAT" type="xs:string" minOccurs="0" />
<xs:element name="TABLE_SCHEM" type="xs:string" minOccurs="0" />
<xs:element name="TABLE_NAME" type="xs:string" minOccurs="0" />
<xs:element name="COLUMN_NAME" type="xs:string" minOccurs="0" />
<xs:element name="KEY_SEQ" type="xs:short" minOccurs="0" />
<xs:element name="PK_NAME" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
More Detailed Data Source Information
<xs:element name="DataSourceInformation">
<xs:complexType>
<xs:sequence>
<xs:element name="CompositeIdentifierSeparatorPattern" type="xs:string" minOccurs="0" />
<xs:element name="DataSourceProductName" type="xs:string" minOccurs="0" />
<xs:element name="DataSourceProductVersion" type="xs:string" minOccurs="0" />
<xs:element name="DataSourceProductVersionNormalized" type="xs:string" minOccurs="0" />
<xs:element name="GroupByBehavior" type="xs:int" minOccurs="0" />
<xs:element name="IdentifierPattern" type="xs:string" minOccurs="0" />
<xs:element name="IdentifierCase" type="xs:int" minOccurs="0" />
<xs:element name="OrderByColumnsInSelect" type="xs:boolean" minOccurs="0" />
<xs:element name="ParameterMarkerFormat" type="xs:string" minOccurs="0" />
<xs:element name="ParameterMarkerPattern" type="xs:string" minOccurs="0" />
<xs:element name="ParameterNameMaxLength" type="xs:int" minOccurs="0" />
<xs:element name="ParameterNamePattern" type="xs:string" minOccurs="0" />
<xs:element name="QuotedIdentifierPattern" type="xs:string" minOccurs="0" />
<xs:element name="QuotedIdentifierCase" type="xs:int" minOccurs="0" />
<xs:element name="StatementSeparatorPattern" type="xs:string" minOccurs="0" />
<xs:element name="StringLiteralPattern" type="xs:string" minOccurs="0" />
<xs:element name="SupportedJoinOperators" type="xs:int" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
In contrast to this very limited information, ODBC can provide far more detailed information about a data source through the
<?xml version="1.0" standalone="yes"?>
<ExtendedDataSourceInformation>
<AggregateFunctions>64</AggregateFunctions>
<AlterDomain>0</AlterDomain>
<AlterTable>39017</AlterTable>
<CatalogLocation>1</CatalogLocation>
<CatalogName>Y</CatalogName>
<CatalogNameSeparator>.</CatalogNameSeparator>
<CatalogTerm>database</CatalogTerm>
<CatalogUsage>7</CatalogUsage>
<CollationSeq>ISO 8859-1</CollationSeq>
<ColumnAlias>Y</ColumnAlias>
<ConcatNullBehavior>0</ConcatNullBehavior>
<ConvertFunctions>3</ConvertFunctions>
<CorrelationName>2</CorrelationName>
<CreateAssertion>0</CreateAssertion>
<CreateCharacterSet>0</CreateCharacterSet>
<CreateCollation>0</CreateCollation>
<CreateDomain>0</CreateDomain>
<CreateSchema>3</CreateSchema>
<CreateTable>1</CreateTable>
<CreateTranslation>0</CreateTranslation>
<CreateView>3</CreateView>
<CursorCommitBehavior>1</CursorCommitBehavior>
<CursorRollbackBehavior>1</CursorRollbackBehavior>
<DatabaseName>cmsb1</DatabaseName>
<DataSourceReadOnly>N</DataSourceReadOnly>
<DDLIndex>3</DDLIndex>
<DefaultTxnIsolation>2</DefaultTxnIsolation>
<DescribeParameter>Y</DescribeParameter>
<DropAssertion>0</DropAssertion>
<DropCharacterSet>0</DropCharacterSet>
<DropCollation>0</DropCollation>
<DropDomain>0</DropDomain>
<DropSchema>0</DropSchema>
<DropTable>1</DropTable>
<DropTranslation>0</DropTranslation>
<DropView>1</DropView>
<ExpressionsInOrderBy>Y</ExpressionsInOrderBy>
<IdentifierQuoteChar>"</IdentifierQuoteChar>
<IndexKeywords>3</IndexKeywords>
<InfoSchemaViews>7585780</InfoSchemaViews>
<InsertStatement>7</InsertStatement>
<Integrity>Y</Integrity>
<LikeEscapeClause>Y</LikeEscapeClause>
<MaxBinaryLiteralLen>524288</MaxBinaryLiteralLen>
<MaxCatalogNameLen>128</MaxCatalogNameLen>
<MaxCharLiteralLen>524288</MaxCharLiteralLen>
<MaxColumnNameLen>128</MaxColumnNameLen>
<MaxColumnsInGroupBy>0</MaxColumnsInGroupBy>
<MaxColumnsInIndex>16</MaxColumnsInIndex>
<MaxColumnsInOrderBy>0</MaxColumnsInOrderBy>
<MaxColumnsInSelect>4096</MaxColumnsInSelect>
<MaxColumnsInTable>1024</MaxColumnsInTable>
<MaxCursorNameLen>128</MaxCursorNameLen>
<MaxIdentifierLen>128</MaxIdentifierLen>
<MaxIndexSize>900</MaxIndexSize>
<MaxProcedureNameLen>134</MaxProcedureNameLen>
<MaxRowSize>8060</MaxRowSize>
<MaxRowSizeIncludesLong>N</MaxRowSizeIncludesLong>
<MaxSchemaNameLen>128</MaxSchemaNameLen>
<MaxStatementLen>524288</MaxStatementLen>
<MaxTableNameLen>128</MaxTableNameLen>
<MaxTablesInSelect>32</MaxTablesInSelect>
<MaxUserNameLen>128</MaxUserNameLen>
<MultResultSets>Y</MultResultSets>
<MultipleActiveTxn>Y</MultipleActiveTxn>
<NonNullableColumns>1</NonNullableColumns>
<NullCollation>1</NullCollation>
<NumericFunctions>16777215</NumericFunctions>
<Procedures>Y</Procedures>
<ProcedureTerm>stored procedure</ProcedureTerm>
<SchemaTerm>owner</SchemaTerm>
<SchemaUsage>31</SchemaUsage>
<SearchPatternEscape>\</SearchPatternEscape>
<SpecialCharacters>....</SpecialCharacters>
<SqlConformance>1</SqlConformance>
<Sql92DateTimeFunctions>0</Sql92DateTimeFunctions>
<Sql92ForeignKeyDeleteRule>0</Sql92ForeignKeyDeleteRule>
<Sql92ForeignKeyUpdateRule>0</Sql92ForeignKeyUpdateRule>
<Sql92Grant>16</Sql92Grant>
<Sql92NumericValueFunctions>0</Sql92NumericValueFunctions>
<Sql92Predicates>7</Sql92Predicates>
<Sql92RelationalJoinOperators>858</Sql92RelationalJoinOperators>
<Sql92Revoke>16</Sql92Revoke>
<Sql92RowValueConstructor>15</Sql92RowValueConstructor>
<Sql92StringFunctions>6</Sql92StringFunctions>
<Sql92ValueExpressions>15</Sql92ValueExpressions>
<StringFunctions>5242879</StringFunctions>
<Subqueries>31</Subqueries>
<SystemFunctions>7</SystemFunctions>
<TableTerm>table</TableTerm>
<TimeDateAddIntervals>511</TimeDateAddIntervals>
<TimeDateDiffIntervals>511</TimeDateDiffIntervals>
<TimeDateFunctions>2097151</TimeDateFunctions>
<TxnCapable>2</TxnCapable>
<TxnIsolationOption>15</TxnIsolationOption>
<Union>3</Union>
</ExtendedDataSourceInformation>
Each of the elements in the above metadata corresponds to a particular
[Flags]
public enum AggregateFunctions : uint
{
All = 0x40,
Avg = 0x01,
Count = 0x02,
Distinct = 0x20,
Max = 0x04,
Min = 0x08,
Sum = 0x10,
}
Enumerations are similarly defined for cases where
public enum CorrelationName : ushort
{
None = 0,
Different = 1,
Any = 2,
}
Metadata Support for ADO.NET 1.x
The
Summary - Promoting Datasource Independence
Referenced by...