程式設計 AMO 基礎物件
基礎物件通常是簡單且直接的物件。通常會建立和具現化這些物件,然後當不再需要時,使用者會將它們中斷連接。基礎類別包括下列物件:Server、Database、DataSource 和 DataSourceView。在 AMO 基礎物件中唯一屬於複雜物件的是 DataSourceView,這需要詳細資料以建立代表資料來源檢視的抽象模型。
通常需要 Server 與 Database 物件以使用所含物件做為 OLAP 物件或是資料採礦物件。
本主題包含下列章節:
伺服器物件
AMOException 例外狀況物件
資料庫物件
DataSource 物件
DataSourceView 物件
伺服器物件
使用 Server 物件需要下列步驟:連接到伺服器、確認 Server 物件是否連接到伺服器,如果已連接,則從伺服器中斷連接 Server。
連接到伺服器物件
連接到伺服器必須有正確的連接字串。
下列程式碼範例會在連接成功時傳回 Server 物件,或是在錯誤發生時傳回 null。在連接處理期間所發生的錯誤,會在 Try/Catch 建構中處理。AMO 錯誤會透過使用 AmoException 例外況狀類別來擷取。在這個範例中,會在訊息方塊中對使用者顯示錯誤。
static Server ServerConnect( String strStringConnection)
{
string methodCaption = "ServerConnect method";
Server svr = new Server();
try
{
svr.Connect(strStringConnection);
}
#region ErrorHandling
catch (AmoException e)
{
MessageBox.Show( "AMO exception " + e.ToString());
svr = null;
}
catch (Exception e)
{
MessageBox.Show("General exception " + e.ToString());
svr = null;
}
#endregion
return svr;
}
連接字串的結構是:
"Data source=<伺服器名稱>"。
如需有關連接字串的詳細資訊,請參閱<ConnectionString>。
驗證連接
在進行 Server 物件的程式設計之前,您應該先確認是否仍然連接到伺服器。下列程式碼範例示範如何執行這項工作。此範例假設 svr 是存在於您的程式碼中的 Server 物件。
if ( (svr != null) && ( svr.Connected))
{
// Do what it is needed if connection is good
}
從伺服器中斷連接
只要您一完成,就可以透過使用 Disconnect 方法從伺服器中斷連接。下列程式碼範例示範如何執行這項工作。此範例假設 svr 是存在於您的程式碼中的 Server 物件。
if ( (svr != null) && ( svr.Connected))
{
svr.Disconnect()
}
AmoException 例外狀況物件
AMO 在找到不同的問題時將會擲回例外狀況。如需例外狀況的詳細說明,請參閱<AMO 其他類別和方法>。下列範例程式碼顯示在 AMO 中擷取例外狀況的正確方法:
try
{
//... some AMO code in here
}
catch ( OutOfSynchException e)
{
// error handling code for OutOfSynchException
}
catch ( OperationException e)
{
// error handling code for OperationException
}
catch ( ResponseFormatException e)
{
// error handling code for ResponseFormatException
}
catch ( ConnectionException e)
{
// error handling code for ConnectionException
}
catch ( AMOException e)
{
//... here is the place where you end if it is an AMO exception, but none of the previous exceptions
// if you start with AMOException in the first catch you will never see any one of the previous exceptions
}
資料庫物件
使用 Database 物件非常簡單且直接。您可以從 Server 物件的資料庫集合取得現有的資料庫。
建立、卸除和尋找資料庫
下列程式碼範例示範如何使用資料庫名稱建立資料庫。在建立資料庫之前,請先查詢伺服器的 DatabaseCollection,以查看資料庫是否存在。如果資料庫存在,會在卸除資料庫之後建立它,如果資料庫不存在,則會建立它。如果要卸除資料庫,則會先從資料庫集合取得資料庫。
static Database CreateDatabase(Server svr, String DatabaseName)
{
Database db = null;
if ( (svr != null) && ( svr.Connected))
{
// Drop the database if it already exists
db = svr.Databases.FindByName(DatabaseName);
if (db != null)
{
db.Drop();
}
// Create the database
db = svr.Databases.Add(DatabaseName);
db.Update();
}
return db;
}
為了判斷某資料庫是否存在於資料庫集合中,會使用 FindByName 方法。如果資料庫存在,該方法會傳回找到的資料庫物件,如果不存在,則會傳回 Null 物件。
只要 Database 物件一加入資料庫集合,就必須使用伺服器的 Update 方法來更新伺服器。無法更新伺服器將造成在伺服器中不會建立 Database 物件。
處理資料庫
處理資料庫及所有的子系物件是非常簡單的,因為 Database 物件包括 Process 方法。
Process 方法可包括參數,但是並非必要。如果未指定參數,將會使用其 ProcessDefault 選項來處理所有的子系物件。如需有關處理選項的詳細資訊,請參閱<Microsoft.AnalysisServices..::..Database>。
- 下列範例程式碼會根據預設值處理資料庫。
static Database ProcessDatabase(Database db, ProcessType pt)
{
db.Process( pt);
return db;
}
DataSource 物件
DataSource 物件是 Analysis Services 與資料所在的資料庫之間的連結。代表 Analysis Services 基礎模型的結構描述是由 DataSourceView 物件所定義。可以將 DataSource 物件視為連至資料所在的資料庫之連接字串。
下列範例程式碼會示範如何建立 DataSource 物件。此範例會確認伺服器是否仍然存在、Server 物件是否已連接,以及資料庫是否已存在。如果 DataSource 物件存在,則會先予以卸除然後重新建立。會建立有相同名稱與內部識別碼的 DataSource 物件。在此範例中,不會在連接字串上執行檢查以進行確認。
static string CreateDataSource(Database db, string strDataSourceName, string strConnectionString)
{
Server svr = db.Parent;
DataSource ds = db.DataSources.FindByName(strDataSourceName);
if (ds != null)
ds.Drop();
// Create the data source
ds = db.DataSources.Add(strDataSourceName, strDataSourceName);
ds.ConnectionString = strConnectionString;
// Send the data source definition to the server.
ds.Update();
return ds.Name;
}
DataSourceView 物件
DataSourceView 物件負責保存 Analysis Services 的結構描述模型。對於保存結構描述的 DataSourceView 物件,必須先建構結構描述。結構描述會從 System.Data 命名空間,透過 DataSet 物件建構。
下列範例程式碼將建立包含在 AdventureWorks Analysis Services Project 範例中的部分結構描述。如需有關安裝範例的詳細資訊,請參閱<AdventureWorks2008R2 範例資料庫>。目前的範例會建立資料表、計算資料行、關聯和複合關聯的結構描述定義。結構描述是保存的資料集。
範例程式碼會執行下列各項:
建立 DataSourceView 物件。
先確認 DataSource 物件是否存在;如果是 true,則先卸除 DataSource 然後再予以建立。如果 DataSource 不存在,則會予以建立。
使用 DataSource 連接字串開啟資料庫的連接。
建立結構描述。
這個結構描述是由下列項目所構成:
資料表定義,AddTable() 方法。
一組選擇性的計算資料行,AddComputedColumn() 方法。
一組選擇性的關聯,AddRelation。
一組選擇性的複合關聯,AddCompositeRelations。
更新伺服器。
[!附註]
下列範例程式碼為提高可讀性已經過修剪,完整的程式碼包括在本主題的結尾。
[!附註]
下列方法屬於範例程式碼的一部分:AddTable、AddComputedColumn、AddRelation 和 AddCompositeRelation。
[!附註]
子句 'WHERE 1=0' 是為了避免查詢將資料列傳回至 DataSet 物件。
static DataSourceView CreateDataSourceView(Database db, string strDataSourceName)
{
// Create the data source view
DataSourceView dsv = db.DataSourceViews.FindByName(strDataSourceName);
if ( dsv != null)
dsv.Drop();
dsv = db.DataSourceViews.Add(strDataSourceName);
dsv.DataSourceID = strDataSourceName;
dsv.Schema = new DataSet();
dsv.Schema.Locale = CultureInfo.CurrentCulture;
// Open a connection to the data source
OleDbConnection connection
= new OleDbConnection(dsv.DataSource.ConnectionString);
connection.Open();
#region Create tables
// Add the DimTime table
AddTable(dsv, connection, "DimTime");
AddComputedColumn(dsv, connection, "DimTime", "SimpleDate", "DATENAME(mm, FullDateAlternateKey) + ' ' + DATENAME(dd, FullDateAlternateKey) + ',' + ' ' + DATENAME(yy, FullDateAlternateKey)");
// Add the DimProductCategory table
AddTable(dsv, connection, "DimProductCategory");
// Add the DimProductSubcategory table
AddTable(dsv, connection, "DimProductSubcategory");
AddRelation(dsv, "DimProductSubcategory", "ProductCategoryKey", "DimProductCategory", "ProductCategoryKey");
// Add the FactInternetSales table
AddTable(dsv, connection, "FactInternetSales");
"DimTime", "TimeKey");
AddRelation(dsv, "FactInternetSales", "ShipDateKey", "DimTime", "TimeKey");
AddRelation(dsv, "FactInternetSales", "DueDateKey", "DimTime", "TimeKey");
// Add the FactInternetSalesReason table
AddTable(dsv, connection, "FactInternetSalesReason");
AddCompositeRelation(dsv, "FactInternetSalesReason", "FactInternetSales", "SalesOrderNumber", "SalesOrderLineNumber");
dsv.Update();
#endregion
// Send the data source view definition to the server
dsv.Update();
return dsv;
}
static void AddTable(DataSourceView dsv, OleDbConnection connection, String tableName)
{
string strSelectText = "SELECT * FROM [dbo].[" + tableName + "] WHERE 1=0";
OleDbDataAdapter adapter = new OleDbDataAdapter(strSelectText, connection);
DataTable[] dataTables = adapter.FillSchema(dsv.Schema,
SchemaType.Mapped, tableName);
DataTable dataTable = dataTables[0];
dataTable.ExtendedProperties.Add("TableType", "Table");
dataTable.ExtendedProperties.Add("DbSchemaName", "dbo");
dataTable.ExtendedProperties.Add("DbTableName", tableName);
dataTable.ExtendedProperties.Add("FriendlyName", tableName);
dataTable = null;
dataTables = null;
adapter = null;
}
static void AddComputedColumn(DataSourceView dsv, OleDbConnection connection, String tableName, String computedColumnName, String expression)
{
DataSet tmpDataSet = new DataSet();
tmpDataSet.Locale = CultureInfo.CurrentCulture;
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT ("
+ expression + ") AS [" + computedColumnName + "] FROM [dbo].["
+ tableName + "] WHERE 1=0", connection);
DataTable[] dataTables = adapter.FillSchema(tmpDataSet,
SchemaType.Mapped, tableName);
DataTable dataTable = dataTables[0];
DataColumn dataColumn = dataTable.Columns[computedColumnName];
dataTable.Constraints.Clear();
dataTable.Columns.Remove(dataColumn);
dataColumn.ExtendedProperties.Add("DbColumnName", computedColumnName);
dataColumn.ExtendedProperties.Add("ComputedColumnExpression",
expression);
dataColumn.ExtendedProperties.Add("IsLogical", "True");
dsv.Schema.Tables[tableName].Columns.Add(dataColumn);
dataColumn = null;
dataTable = null;
dataTables = null;
adapter = null;
tmpDataSet = null;
}
static void AddRelation(DataSourceView dsv, String fkTableName, String fkColumnName, String pkTableName, String pkColumnName)
{
DataColumn fkColumn
= dsv.Schema.Tables[fkTableName].Columns[fkColumnName];
DataColumn pkColumn
= dsv.Schema.Tables[pkTableName].Columns[pkColumnName];
dsv.Schema.Relations.Add("FK_" + fkTableName + "_"
+ fkColumnName, pkColumn, fkColumn, true);
}
static void AddCompositeRelation(DataSourceView dsv, String fkTableName, String pkTableName, String columnName1, String columnName2)
{
DataColumn[] fkColumns = new DataColumn[2];
fkColumns[0] = dsv.Schema.Tables[fkTableName].Columns[columnName1];
fkColumns[1] = dsv.Schema.Tables[fkTableName].Columns[columnName2];
DataColumn[] pkColumns = new DataColumn[2];
pkColumns[0] = dsv.Schema.Tables[pkTableName].Columns[columnName1];
pkColumns[1] = dsv.Schema.Tables[pkTableName].Columns[columnName2];
dsv.Schema.Relations.Add("FK_" + fkTableName + "_" + columnName1
+ "_" + columnName2, pkColumns, fkColumns, true);
}
在範例程式碼中,AddTable 和 AddComputedColumn 方法使用 DataAdapter 物件的 FillSchema 方法,將 DataTable 加入 DataSet,並將結構描述設定成符合資料來源中的結構描述。擴充屬性會加入所需的資訊以設定 Analysis Services 的結構描述。
在範例程式碼中,AddRelation 與 AddCompositeRelation 方法會加入關聯資料行,端視現有結構描述與模型上的現有資料行而定。資料行必須屬於定義在結構描述內的資料表,這些方法才能運作。
下列是完整的程式碼範例:
static DataSourceView CreateDataSourceView(Database db, string strDataSourceName)
{
// Create the data source view
DataSourceView dsv = db.DataSourceViews.FindByName(strDataSourceName);
if ( dsv != null)
dsv.Drop();
dsv = db.DataSourceViews.Add(strDataSourceName);
dsv.DataSourceID = strDataSourceName;
dsv.Schema = new DataSet();
dsv.Schema.Locale = CultureInfo.CurrentCulture;
// Open a connection to the data source
OleDbConnection connection
= new OleDbConnection(dsv.DataSource.ConnectionString);
connection.Open();
#region Create tables
// Add the DimTime table
AddTable(dsv, connection, "DimTime");
AddComputedColumn(dsv, connection, "DimTime", "SimpleDate", "DATENAME(mm, FullDateAlternateKey) + ' ' + DATENAME(dd, FullDateAlternateKey) + ',' + ' ' + DATENAME(yy, FullDateAlternateKey)");
AddComputedColumn(dsv, connection, "DimTime", "CalendarYearDesc", "'CY' + ' ' + CalendarYear");
AddComputedColumn(dsv, connection, "DimTime", "CalendarSemesterDesc", "CASE WHEN CalendarSemester = 1 THEN 'H1'+' '+ 'CY' +' '+ CONVERT(CHAR (4), CalendarYear) ELSE 'H2'+' '+ 'CY' +' '+ CONVERT(CHAR (4), CalendarYear) END");
AddComputedColumn(dsv, connection, "DimTime", "CalendarQuarterDesc", "'Q' + CONVERT(CHAR (1), CalendarQuarter) +' '+ 'CY' +' '+ CONVERT(CHAR (4), CalendarYear)");
AddComputedColumn(dsv, connection, "DimTime", "MonthName", "EnglishMonthName+' '+ CONVERT(CHAR (4), CalendarYear)");
AddComputedColumn(dsv, connection, "DimTime", "FiscalYearDesc", "'FY' + ' ' + FiscalYear");
AddComputedColumn(dsv, connection, "DimTime", "FiscalSemesterDesc", "CASE WHEN FiscalSemester = 1 THEN 'H1'+' '+ 'FY' +' '+ CONVERT(CHAR (4), FiscalYear) ELSE 'H2'+' '+ 'FY' +' '+ CONVERT(CHAR (4), FiscalYear) END");
AddComputedColumn(dsv, connection, "DimTime", "FiscalQuarterDesc", "'Q' + CONVERT(CHAR (1), FiscalQuarter) +' '+ 'FY' +' '+ CONVERT(CHAR (4), FiscalYear)");
AddComputedColumn(dsv, connection, "DimTime", "FiscalMonthNumberOfYear", "CASE WHEN MonthNumberOfYear = '1' THEN CONVERT(int,'7') WHEN MonthNumberOfYear = '2' THEN CONVERT(int,'8') WHEN MonthNumberOfYear = '3' THEN CONVERT(int,'9') WHEN MonthNumberOfYear = '4' THEN CONVERT(int,'10') WHEN MonthNumberOfYear = '5' THEN CONVERT(int,'11') WHEN MonthNumberOfYear = '6' THEN CONVERT(int,'12') WHEN MonthNumberOfYear = '7' THEN CONVERT(int,'1') WHEN MonthNumberOfYear = '8' THEN CONVERT(int,'2') WHEN MonthNumberOfYear = '9' THEN CONVERT(int,'3') WHEN MonthNumberOfYear = '10' THEN CONVERT(int,'4') WHEN MonthNumberOfYear = '11' THEN CONVERT(int,'5') WHEN MonthNumberOfYear = '12' THEN CONVERT(int,'6') END");
dsv.Update();
// Add the DimGeography table
AddTable(dsv, connection, "DimGeography");
// Add the DimProductCategory table
AddTable(dsv, connection, "DimProductCategory");
// Add the DimProductSubcategory table
AddTable(dsv, connection, "DimProductSubcategory");
AddRelation(dsv, "DimProductSubcategory", "ProductCategoryKey", "DimProductCategory", "ProductCategoryKey");
// Add the DimProduct table
AddTable(dsv, connection, "DimProduct");
AddComputedColumn(dsv, connection, "DimProduct", "ProductLineName", "CASE ProductLine WHEN 'M' THEN 'Mountain' WHEN 'R' THEN 'Road' WHEN 'S' THEN 'Accessory' WHEN 'T' THEN 'Touring' ELSE 'Components' END");
AddRelation(dsv, "DimProduct", "ProductSubcategoryKey", "DimProductSubcategory", "ProductSubcategoryKey");
dsv.Update();
// Add the DimCustomer table
AddTable(dsv, connection, "DimCustomer");
AddComputedColumn(dsv, connection, "DimCustomer", "FullName", "CASE WHEN MiddleName IS NULL THEN FirstName + ' ' + LastName ELSE FirstName + ' ' + MiddleName + ' ' + LastName END");
AddComputedColumn(dsv, connection, "DimCustomer", "GenderDesc", "CASE WHEN Gender = 'M' THEN 'Male' ELSE 'Female' END");
AddComputedColumn(dsv, connection, "DimCustomer", "MaritalStatusDesc", "CASE WHEN MaritalStatus = 'S' THEN 'Single' ELSE 'Married' END");
AddRelation(dsv, "DimCustomer", "GeographyKey", "DimGeography", "GeographyKey");
// Add the DimReseller table
AddTable(dsv, connection, "DimReseller");
AddComputedColumn(dsv, connection, "DimReseller", "OrderFrequencyDesc", "CASE WHEN OrderFrequency = 'A' THEN 'Annual' WHEN OrderFrequency = 'S' THEN 'Bi-Annual' ELSE 'Quarterly' END");
AddComputedColumn(dsv, connection, "DimReseller", "OrderMonthDesc", "CASE WHEN OrderMonth = '1' THEN 'January' WHEN OrderMonth = '2' THEN 'February' WHEN OrderMonth = '3' THEN 'March' WHEN OrderMonth = '4' THEN 'April' WHEN OrderMonth = '5' THEN 'May' WHEN OrderMonth = '6' THEN 'June' WHEN OrderMonth = '7' THEN 'July' WHEN OrderMonth = '8' THEN 'August' WHEN OrderMonth = '9' THEN 'September' WHEN OrderMonth = '10' THEN 'October' WHEN OrderMonth = '11' THEN 'November' WHEN OrderMonth = '12' THEN 'December' ELSE 'Never Ordered' END");
// Add the DimCurrency table
AddTable(dsv, connection, "DimCurrency");
dsv.Update();
// Add the DimSalesReason table
AddTable(dsv, connection, "DimSalesReason");
// Add the FactInternetSales table
AddTable(dsv, connection, "FactInternetSales");
AddRelation(dsv, "FactInternetSales", "ProductKey", "DimProduct", "ProductKey");
AddRelation(dsv, "FactInternetSales", "CustomerKey", "DimCustomer", "CustomerKey");
AddRelation(dsv, "FactInternetSales", "OrderDateKey", "DimTime", "TimeKey");
AddRelation(dsv, "FactInternetSales", "ShipDateKey", "DimTime", "TimeKey");
AddRelation(dsv, "FactInternetSales", "DueDateKey", "DimTime", "TimeKey");
AddRelation(dsv, "FactInternetSales", "CurrencyKey", "DimCurrency", "CurrencyKey");
dsv.Update();
// Add the FactResellerSales table
AddTable(dsv, connection, "FactResellerSales");
AddRelation(dsv, "FactResellerSales", "ProductKey", "DimProduct", "ProductKey");
AddRelation(dsv, "FactResellerSales", "ResellerKey", "DimReseller", "ResellerKey");
AddRelation(dsv, "FactResellerSales", "OrderDateKey", "DimTime", "TimeKey");
AddRelation(dsv, "FactResellerSales", "ShipDateKey", "DimTime", "TimeKey");
AddRelation(dsv, "FactResellerSales", "DueDateKey", "DimTime", "TimeKey");
AddRelation(dsv, "FactResellerSales", "CurrencyKey", "DimCurrency", "CurrencyKey");
// Add the FactInternetSalesReason table
AddTable(dsv, connection, "FactInternetSalesReason");
AddCompositeRelation(dsv, "FactInternetSalesReason", "FactInternetSales", "SalesOrderNumber", "SalesOrderLineNumber");
dsv.Update();
// Add the FactCurrencyRate table
AddTable(dsv, connection, "FactCurrencyRate");
AddRelation(dsv, "FactCurrencyRate", "CurrencyKey", "DimCurrency", "CurrencyKey");
AddRelation(dsv, "FactCurrencyRate", "TimeKey", "DimTime", "TimeKey");
#endregion
// Send the data source view definition to the server
dsv.Update();
return dsv;
}
static void AddTable(DataSourceView dsv, OleDbConnection connection, String tableName)
{
string strSelectText = "SELECT * FROM [dbo].[" + tableName + "] WHERE 1=0";
OleDbDataAdapter adapter = new OleDbDataAdapter(strSelectText, connection);
DataTable[] dataTables = adapter.FillSchema(dsv.Schema,
SchemaType.Mapped, tableName);
DataTable dataTable = dataTables[0];
dataTable.ExtendedProperties.Add("TableType", "Table");
dataTable.ExtendedProperties.Add("DbSchemaName", "dbo");
dataTable.ExtendedProperties.Add("DbTableName", tableName);
dataTable.ExtendedProperties.Add("FriendlyName", tableName);
dataTable = null;
dataTables = null;
adapter = null;
}
static void AddComputedColumn(DataSourceView dsv, OleDbConnection connection, String tableName, String computedColumnName, String expression)
{
DataSet tmpDataSet = new DataSet();
tmpDataSet.Locale = CultureInfo.CurrentCulture;
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT ("
+ expression + ") AS [" + computedColumnName + "] FROM [dbo].["
+ tableName + "] WHERE 1=0", connection);
DataTable[] dataTables = adapter.FillSchema(tmpDataSet,
SchemaType.Mapped, tableName);
DataTable dataTable = dataTables[0];
DataColumn dataColumn = dataTable.Columns[computedColumnName];
dataTable.Constraints.Clear();
dataTable.Columns.Remove(dataColumn);
dataColumn.ExtendedProperties.Add("DbColumnName", computedColumnName);
dataColumn.ExtendedProperties.Add("ComputedColumnExpression",
expression);
dataColumn.ExtendedProperties.Add("IsLogical", "True");
dsv.Schema.Tables[tableName].Columns.Add(dataColumn);
dataColumn = null;
dataTable = null;
dataTables = null;
adapter = null;
tmpDataSet = null;
}
static void AddRelation(DataSourceView dsv, String fkTableName, String fkColumnName, String pkTableName, String pkColumnName)
{
DataColumn fkColumn
= dsv.Schema.Tables[fkTableName].Columns[fkColumnName];
DataColumn pkColumn
= dsv.Schema.Tables[pkTableName].Columns[pkColumnName];
dsv.Schema.Relations.Add("FK_" + fkTableName + "_"
+ fkColumnName, pkColumn, fkColumn, true);
}
static void AddCompositeRelation(DataSourceView dsv, String fkTableName, String pkTableName, String columnName1, String columnName2)
{
DataColumn[] fkColumns = new DataColumn[2];
fkColumns[0] = dsv.Schema.Tables[fkTableName].Columns[columnName1];
fkColumns[1] = dsv.Schema.Tables[fkTableName].Columns[columnName2];
DataColumn[] pkColumns = new DataColumn[2];
pkColumns[0] = dsv.Schema.Tables[pkTableName].Columns[columnName1];
pkColumns[1] = dsv.Schema.Tables[pkTableName].Columns[columnName2];
dsv.Schema.Relations.Add("FK_" + fkTableName + "_" + columnName1
+ "_" + columnName2, pkColumns, fkColumns, true);
}