PageRenderTime 54ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/Main/DependencyAnalyzer2008/SSASEnumerator.cs

#
C# | 707 lines | 472 code | 115 blank | 120 comment | 80 complexity | d81d6a6966fd4eed115bd0faec8a1473 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. ///
  2. /// Microsoft SQL Server 2005 Business Intelligence Metadata Reporting Samples
  3. /// Dependency Analyzer Sample
  4. ///
  5. /// Copyright (c) Microsoft Corporation. All rights reserved.
  6. ///
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Data;
  10. using System.Diagnostics;
  11. using System.Text;
  12. using Microsoft.AnalysisServices;
  13. namespace Microsoft.Samples.DependencyAnalyzer
  14. {
  15. /// <summary>
  16. /// Enumerates Analysis Services objects and the relationships between them.
  17. /// The result of this enumeration is persisted in a repository.
  18. /// </summary>
  19. class SSASEnumerator
  20. {
  21. /// <summary>
  22. /// For storing repository information
  23. /// </summary>
  24. private class DsvRepositoryInformation
  25. {
  26. public int dsvID;
  27. public Dictionary<string, int> dsvTableNameToIDMap;
  28. }
  29. private Repository repository;
  30. private bool threePartNames;
  31. /// <summary>
  32. /// Types of Analysis Services objects we recognise for the repository
  33. /// </summary>
  34. private class ObjectTypes
  35. {
  36. internal const string Server = "Ssas.Analysis Server";
  37. internal const string Database = "Ssas.Database";
  38. internal const string Cube = "Ssas.Cube";
  39. internal const string CubeDimension = "Ssas.Cube Dimension";
  40. internal const string MeasureGroup = "Ssas.Measure Group";
  41. internal const string MeasureGroupDimension = "Ssas.Measure Group Dimension";
  42. internal const string Partition = "Ssas.Partition";
  43. internal const string DatabaseDimension = "Ssas.Database Dimension";
  44. internal const string DataSource = "Ssas.DataSource";
  45. internal const string DataSourceView = "Ssas.DSV";
  46. internal const string DataSourceViewTable = "Ssas.DSV Table";
  47. }
  48. /// <summary>
  49. /// since we can't get the quoting characters offline, we'll have to hard code them here.
  50. /// </summary>
  51. private class QuotingCharacters
  52. {
  53. public static string OpenQuote = "[";
  54. public static string CloseQuote = "]";
  55. }
  56. public bool Initialize(Repository repository)
  57. {
  58. this.repository = repository;
  59. // add types of objects to the object types table
  60. AddASObjectType(ObjectTypes.Server, "Analysis Server");
  61. AddASObjectType(ObjectTypes.Database, "Database");
  62. AddASObjectType(ObjectTypes.DataSource, "Data Source");
  63. AddASObjectType(ObjectTypes.DataSourceView, "Data Source View");
  64. AddASObjectType(ObjectTypes.DataSourceViewTable, "Data Source View Table");
  65. AddASObjectType(ObjectTypes.Cube, "Cube");
  66. AddASObjectType(ObjectTypes.MeasureGroup, "Measure Group");
  67. AddASObjectType(ObjectTypes.Partition, "Partition");
  68. AddASObjectType(ObjectTypes.DatabaseDimension, "Database Dimension");
  69. AddASObjectType(ObjectTypes.CubeDimension, "Cube Dimension");
  70. AddASObjectType(ObjectTypes.MeasureGroupDimension, "Measure Group Dimension");
  71. return true;
  72. }
  73. private void AddASObjectType(string type, string name)
  74. {
  75. repository.AddObjectType(Repository.Domains.SSAS, type, name);
  76. }
  77. /// <summary>
  78. /// Opens a connection to the Analysis Server and does the actual object model walk
  79. /// </summary>
  80. /// <param name="connectionString"></param>
  81. public void EnumerateServer(string connectionString, bool storeThreePartNames)
  82. {
  83. threePartNames = storeThreePartNames;
  84. using (Microsoft.AnalysisServices.Server server = new Server())
  85. {
  86. server.Connect(connectionString);
  87. int svID = repository.AddObject(server.Name, server.Description, ObjectTypes.Server, 0);
  88. if (connectionString.ToLower().Contains("catalog"))
  89. {
  90. Database db = server.Databases[server.ConnectionInfo.Catalog];
  91. Console.Write(string.Format("Enumerating '{0}'...", db.Name));
  92. EnumerateDatabase(svID, db);
  93. Console.WriteLine("Done");
  94. }
  95. else
  96. {
  97. // get the databases
  98. foreach (Database db in server.Databases)
  99. {
  100. Console.Write(string.Format("Enumerating '{0}'...", db.Name));
  101. EnumerateDatabase(svID, db);
  102. Console.WriteLine("Done");
  103. }
  104. }
  105. }
  106. }
  107. private void EnumerateDatabase(int svID, Database db)
  108. {
  109. int dbID = repository.AddObject(db.Name, db.Description, ObjectTypes.Database, svID);
  110. Dictionary<DataSource, int> dsToIdMap;
  111. EnumerateDataSources(db, dbID, out dsToIdMap);
  112. Dictionary<DataSourceView, DsvRepositoryInformation> dsvToObjectIDMap;
  113. EnumerateDataSourceViews(db, dbID, out dsvToObjectIDMap);
  114. Dictionary<Dimension, int> dimensionToIDMap;
  115. EnumerateDimensions(db, dbID, dsvToObjectIDMap, dsToIdMap, out dimensionToIDMap);
  116. EnumerateCubes(db, dbID, dsvToObjectIDMap, dsToIdMap, dimensionToIDMap);
  117. }
  118. private void EnumerateDataSourceViews(Database db, int dbID, out Dictionary<DataSourceView, DsvRepositoryInformation> dsvToObjectIDMap)
  119. {
  120. dsvToObjectIDMap = new Dictionary<DataSourceView, DsvRepositoryInformation>();
  121. foreach (DataSourceView dsv in db.DataSourceViews)
  122. {
  123. // get the connection ID
  124. int connectionID = -1;
  125. if (dsv.DataSource != null)
  126. {
  127. connectionID = repository.GetConnection(dsv.DataSource.ConnectionString);
  128. if (connectionID == -1)
  129. {
  130. connectionID = CreateConnection(dsv.DataSource);
  131. }
  132. }
  133. // a DSV might exist without a data source. So, we have to use the database as the parent.
  134. int dsvID = repository.AddObject(dsv.Name, dsv.Description, ObjectTypes.DataSourceView, dbID);
  135. DsvRepositoryInformation dsvRepositoryInformation = new DsvRepositoryInformation();
  136. dsvRepositoryInformation.dsvID = dsvID;
  137. EnumerateDsvTables(dsv, connectionID, dsvID, out dsvRepositoryInformation.dsvTableNameToIDMap);
  138. dsvToObjectIDMap.Add(dsv, dsvRepositoryInformation);
  139. }
  140. }
  141. private int CreateConnection(DataSource ds)
  142. {
  143. int connectionID = repository.AddObject(ds.Name, string.Empty, ds.GetType().Name, repository.RootRepositoryObjectID);
  144. // add the attributes of the connection as well
  145. repository.AddAttribute(connectionID, Repository.Attributes.ConnectionString, ds.ConnectionString);
  146. /*// get the server name/initial catalog, etc.
  147. string serverName;
  148. string initialCatalog;
  149. GetConnectionAttributes(connectionManager, out serverName, out initialCatalog);
  150. if (string.IsNullOrEmpty(serverName) == false)
  151. {
  152. repository.AddAttribute(connectionID, attributeConnectionServer, serverName);
  153. }
  154. if (string.IsNullOrEmpty(initialCatalog) == false)
  155. {
  156. repository.AddAttribute(connectionID, attributeConnectionDatabase, initialCatalog);
  157. }
  158. */
  159. return connectionID;
  160. }
  161. private void EnumerateDsvTables(DataSourceView dsv, int connectionID, int dsvID, out Dictionary<string,int> tableNameToIDMap)
  162. {
  163. tableNameToIDMap = new Dictionary<string, int>(dsv.Schema.Tables.Count);
  164. foreach (DataTable table in dsv.Schema.Tables)
  165. {
  166. string tableType = GetExtendedProperty(table, ExtendedProperties.TableType);
  167. // add the data source view
  168. int dsvTableID = repository.AddObject(table.TableName, string.Empty, ObjectTypes.DataSourceViewTable, dsvID);
  169. tableNameToIDMap.Add(table.TableName, dsvTableID);
  170. if (connectionID != -1)
  171. {
  172. if (tableType == ExtendedProperties.TableTypeValue)
  173. {
  174. // this is mapped to an underlying table
  175. // now add the table
  176. string tableName = GetFullyQualifiedTableName(table);
  177. if (threePartNames)
  178. tableName = String.Format("[{0}].{1}", repository.RetrieveDatabaseNameFromConnectionID(connectionID), tableName);
  179. int tableID = repository.GetTable(connectionID, tableName);
  180. if (tableID == -1)
  181. {
  182. tableID = repository.AddObject(tableName, string.Empty, RelationalEnumerator.ObjectTypes.Table, connectionID);
  183. }
  184. // add the lineage
  185. repository.AddMapping(tableID, dsvTableID);
  186. }
  187. else
  188. {
  189. if (tableType == ExtendedProperties.ViewTypeValue)
  190. {
  191. // add the query definition
  192. object queryDefinition = table.ExtendedProperties["QueryDefinition"];
  193. if (queryDefinition != null)
  194. {
  195. repository.AddAttribute(dsvTableID, Repository.Attributes.QueryDefinition, queryDefinition.ToString());
  196. }
  197. }
  198. }
  199. }
  200. }
  201. }
  202. private void EnumerateDataSources(Database db, int dbID, out Dictionary<DataSource,int> dsToIdMap)
  203. {
  204. dsToIdMap = new Dictionary<DataSource, int>(db.DataSources.Count);
  205. foreach (DataSource ds in db.DataSources)
  206. {
  207. int dsID = repository.AddObject(ds.Name, ds.Description, ObjectTypes.DataSource, dbID);
  208. // add connections
  209. int connectionID = repository.GetConnection(ds.ConnectionString);
  210. if (connectionID == -1)
  211. {
  212. connectionID = repository.AddObject(ds.Name, ds.Description, string.Empty, repository.RootRepositoryObjectID);
  213. }
  214. dsToIdMap.Add(ds, connectionID);
  215. }
  216. }
  217. private void EnumerateDimensions(Database db, int dbID, Dictionary<DataSourceView, DsvRepositoryInformation> dsvToObjectIDMap, Dictionary<DataSource, int> dsToIDMap, out Dictionary<Dimension, int> dimensionToIdMap)
  218. {
  219. dimensionToIdMap = new Dictionary<Dimension, int>(db.Dimensions.Count);
  220. foreach (Dimension dim in db.Dimensions)
  221. {
  222. // get the connection ID
  223. int connectionID = -1;
  224. if ((dim.DataSource != null ) && (dsToIDMap.ContainsKey(dim.DataSource)))
  225. {
  226. connectionID = dsToIDMap[dim.DataSource];
  227. }
  228. DsvRepositoryInformation dsvRepositoryInformation = dsvToObjectIDMap[dim.DataSourceView];
  229. Dictionary<string,int> dsvTableNameToIdMap = dsvRepositoryInformation.dsvTableNameToIDMap;
  230. int dimID = repository.AddObject(dim.Name, dim.Description, ObjectTypes.DatabaseDimension, dbID);
  231. dimensionToIdMap.Add(dim, dimID);
  232. Dictionary<int,bool> sourceTableIDs = new Dictionary<int,bool>();
  233. foreach (DimensionAttribute attr in dim.Attributes)
  234. {
  235. if (connectionID > -1)
  236. {
  237. string query;
  238. int sourceTableID = GetSourceIDForBinding(connectionID, dsvTableNameToIdMap, attr.NameColumn.Source, out query);
  239. if (sourceTableID > 0)
  240. {
  241. // since we track only table level dependencies and not at the column level,
  242. // we have to create a distinct list of these source tables
  243. sourceTableIDs[sourceTableID] = true;
  244. }
  245. else
  246. {
  247. // if we don't have a table ID but have a query, store that as an attribute
  248. // so that users can at least take a look at the query itself.
  249. if (query != null)
  250. {
  251. repository.AddAttribute(dimID, Repository.Attributes.QueryDefinition, query);
  252. }
  253. }
  254. }
  255. }
  256. // now create the lineage map from the distinct list of source tables to the dimension
  257. foreach(int sourceTableID in sourceTableIDs.Keys)
  258. {
  259. repository.AddMapping(sourceTableID, dimID);
  260. }
  261. }
  262. }
  263. /// <summary>
  264. /// returns information about the binding for table/dsvTable or ColumnBinding, we return the table ID
  265. /// for query binding, the returned value is -1, but the query out parameter is set to the query definition
  266. /// </summary>
  267. /// <param name="connectionID"></param>
  268. /// <param name="dsvTableNameToIdMap"></param>
  269. /// <param name="binding"></param>
  270. /// <param name="?"></param>
  271. /// <returns></returns>
  272. private int GetSourceIDForBinding(int connectionID, Dictionary<string, int> dsvTableNameToIdMap, Binding binding, out string query)
  273. {
  274. int sourceID = -1;
  275. query = null;
  276. if (binding != null)
  277. {
  278. if (binding is ColumnBinding)
  279. {
  280. ColumnBinding colBinding = (ColumnBinding)binding;
  281. // get the id of the dsv table colBinding.TableID
  282. if (dsvTableNameToIdMap.ContainsKey(colBinding.TableID))
  283. {
  284. sourceID = dsvTableNameToIdMap[colBinding.TableID];
  285. }
  286. }
  287. else
  288. {
  289. if (binding is DsvTableBinding)
  290. {
  291. DsvTableBinding dsvTableBinding = (DsvTableBinding)binding;
  292. if (dsvTableNameToIdMap.ContainsKey(dsvTableBinding.TableID))
  293. {
  294. sourceID = dsvTableNameToIdMap[dsvTableBinding.TableID];
  295. }
  296. }
  297. else
  298. {
  299. if (binding is TableBinding)
  300. {
  301. TableBinding tableBinding = (TableBinding)binding;
  302. string tableName = GetFullyQualifiedTableName(tableBinding.DbSchemaName, tableBinding.DbTableName);
  303. if (threePartNames)
  304. tableName = String.Format("[{0}].{1}", repository.RetrieveDatabaseNameFromConnectionID(connectionID), tableName);
  305. // get the table name from the repository itself
  306. sourceID = repository.GetTable(connectionID, tableName);
  307. if (sourceID == -1)
  308. {
  309. sourceID = repository.AddObject(tableName, string.Empty, RelationalEnumerator.ObjectTypes.Table, connectionID);
  310. }
  311. }
  312. else
  313. {
  314. if (binding is MeasureGroupDimensionBinding)
  315. {
  316. // the caller will handle this since we need the list of cb dimensions
  317. }
  318. else
  319. {
  320. if (binding is QueryBinding)
  321. {
  322. QueryBinding queryBinding = (QueryBinding)binding;
  323. query = queryBinding.QueryDefinition;
  324. }
  325. }
  326. }
  327. }
  328. }
  329. }
  330. return sourceID;
  331. }
  332. private void EnumerateCubes(Database db, int dbID, Dictionary<DataSourceView, DsvRepositoryInformation> dsvToRepositoryMap, Dictionary<DataSource, int> dsToIdMap, Dictionary<Dimension, int> dimensionToIDMap)
  333. {
  334. Dictionary<string, int> emptyDsvTableToIdMap = new Dictionary<string, int>();
  335. foreach (Cube cb in db.Cubes)
  336. {
  337. int connectionID = dsToIdMap[cb.DataSource];
  338. int cbID = repository.AddObject(cb.Name, cb.Description, ObjectTypes.Cube, dbID);
  339. Dictionary<CubeDimension, int> cubeDimensionToIDMap = new Dictionary<CubeDimension, int>();
  340. foreach (CubeDimension cbDim in cb.Dimensions)
  341. {
  342. int cbDimID = repository.AddObject(cbDim.Name, cbDim.Description, ObjectTypes.CubeDimension, cbID);
  343. // add Use dependency between the cube dimension and the database dimension
  344. repository.AddUseDependency(dimensionToIDMap[cbDim.Dimension], cbDimID);
  345. cubeDimensionToIDMap.Add(cbDim, cbDimID);
  346. }
  347. EnumerateMeasureGroups(dsvToRepositoryMap, emptyDsvTableToIdMap, cb, connectionID, cbID, cubeDimensionToIDMap);
  348. }
  349. }
  350. /// <summary>
  351. /// enumerates measures groups, mg dimensions and partitions.
  352. /// </summary>
  353. /// <param name="dsvToRepositoryMap"></param>
  354. /// <param name="emptyDsvTableToIdMap"></param>
  355. /// <param name="cb"></param>
  356. /// <param name="connectionID"></param>
  357. /// <param name="cbID"></param>
  358. /// <param name="cubeDimensionToIDMap"></param>
  359. private void EnumerateMeasureGroups(Dictionary<DataSourceView, DsvRepositoryInformation> dsvToRepositoryMap, Dictionary<string, int> emptyDsvTableToIdMap, Cube cb, int connectionID, int cbID, Dictionary<CubeDimension, int> cubeDimensionToIDMap)
  360. {
  361. // measure group
  362. foreach (MeasureGroup mg in cb.MeasureGroups)
  363. {
  364. int mgID = repository.AddObject(mg.Name, mg.Description, ObjectTypes.MeasureGroup, cbID);
  365. // partition
  366. foreach (Partition pt in mg.Partitions)
  367. {
  368. int ptID = repository.AddObject(pt.Name, pt.Description, ObjectTypes.Partition, mgID);
  369. Dictionary<string, int> dsvTableToIdMap = emptyDsvTableToIdMap;
  370. if ((pt.DataSourceView != null) && (dsvToRepositoryMap.ContainsKey(pt.DataSourceView)))
  371. {
  372. dsvTableToIdMap = dsvToRepositoryMap[pt.DataSourceView].dsvTableNameToIDMap;
  373. }
  374. // add the mapping
  375. string query;
  376. int sourceTableID = GetSourceIDForBinding(connectionID, dsvTableToIdMap, pt.Source, out query);
  377. if (sourceTableID > 0)
  378. {
  379. repository.AddMapping(sourceTableID, ptID);
  380. }
  381. else
  382. {
  383. // if we don't have a table ID but have a query, store that as an attribute
  384. // so that users can at least take a look at the query itself.
  385. if (query != null)
  386. {
  387. repository.AddAttribute(ptID, Repository.Attributes.QueryDefinition, query);
  388. }
  389. }
  390. }
  391. EnumerateMeasureGroupDimensions(dsvToRepositoryMap, connectionID, cubeDimensionToIDMap, mg, mgID);
  392. }
  393. }
  394. private void EnumerateMeasureGroupDimensions(Dictionary<DataSourceView, DsvRepositoryInformation> dsvToRepositoryMap, int connectionID, Dictionary<CubeDimension, int> cubeDimensionToIDMap, MeasureGroup mg, int mgID)
  395. {
  396. foreach (MeasureGroupDimension mgDim in mg.Dimensions)
  397. {
  398. if (mgDim.Dimension != null)
  399. {
  400. Dictionary<string, int> dsvTableNameToIdMap = dsvToRepositoryMap[mgDim.Dimension.DataSourceView].dsvTableNameToIDMap;
  401. Dictionary<int, bool> distinctTableIDsList = new Dictionary<int, bool>();
  402. int mgDimID = repository.AddObject(mgDim.Dimension.Name, mgDim.Dimension.Description, ObjectTypes.MeasureGroupDimension, mgID);
  403. // add a Use dependency from cubeDim->mgdim
  404. repository.AddUseDependency(cubeDimensionToIDMap[mgDim.CubeDimension], mgDimID);
  405. // this handles ReferenceMeasureGroupDimension and DegenerateMeasureGroupDimension as well.
  406. RegularMeasureGroupDimension rmgdim = mgDim as RegularMeasureGroupDimension;
  407. if (rmgdim != null)
  408. {
  409. foreach (MeasureGroupAttribute mgDimAttr in rmgdim.Attributes)
  410. {
  411. foreach (DataItem keyColumn in mgDimAttr.KeyColumns)
  412. {
  413. string query;
  414. int sourceTableID = GetSourceIDForBinding(connectionID, dsvTableNameToIdMap, keyColumn.Source, out query);
  415. if (sourceTableID > 0)
  416. {
  417. distinctTableIDsList[sourceTableID] = true;
  418. }
  419. else
  420. {
  421. // if we don't have a table ID but have a query, store that as an attribute
  422. // so that users can at least take a look at the query itself.
  423. if (query != null)
  424. {
  425. repository.AddAttribute(mgDimID, Repository.Attributes.QueryDefinition, query);
  426. }
  427. }
  428. }
  429. }
  430. }
  431. // add a lineage map from the tables to the measure group dim
  432. foreach (int tableID in distinctTableIDsList.Keys)
  433. {
  434. repository.AddMapping(tableID, mgDimID);
  435. }
  436. }
  437. }
  438. }
  439. private string GetFullyQualifiedTableName(DataTable dataTable)
  440. {
  441. return GetFullyQualifiedTableName(GetSchemaName(dataTable), GetTableName(dataTable));
  442. }
  443. private string GetFullyQualifiedTableName(string schemaName, string tableName)
  444. {
  445. return EncodeTableFullName(schemaName, tableName, QuotingCharacters.OpenQuote, QuotingCharacters.CloseQuote);
  446. }
  447. /// <summary>
  448. /// Helper function encode full table name
  449. /// </summary>
  450. /// <param name="schemaName"></param>
  451. /// <param name="objName"></param>
  452. /// <param name="openQuote"></param>
  453. /// <param name="closeQuote"></param>
  454. /// <returns></returns>
  455. private string EncodeTableFullName(string schemaName, string objName, string openQuote, string closeQuote)
  456. {
  457. if (schemaName == null || schemaName.Length == 0)
  458. return EncodeObjectName(objName, openQuote, closeQuote);
  459. else
  460. return (String.Format("{0}.{1}", EncodeObjectName(schemaName, openQuote, closeQuote),
  461. EncodeObjectName(objName, openQuote, closeQuote)));
  462. }
  463. /// <summary>
  464. /// Encode Object Name
  465. /// </summary>
  466. /// <param name="objectName">Object Name</param>
  467. /// <returns>Encoded Object Name</returns>
  468. public static string EncodeObjectName(string objectName, string openQuote, string closeQuote)
  469. {
  470. Debug.Assert(openQuote != null, "Undefined open quote.");
  471. Debug.Assert(closeQuote != null, "Undefined close quote.");
  472. if (objectName == null)
  473. return "";
  474. if (objectName.Trim().Length == 0)
  475. return "";
  476. if (openQuote == null || closeQuote == null)
  477. return objectName;
  478. string newName = objectName.Replace(closeQuote, closeQuote + closeQuote);
  479. return (String.Format("{0}{1}{2}", openQuote, newName, closeQuote));
  480. }
  481. /// <summary>
  482. /// Gets the Schema name for the given dataTable.
  483. /// </summary>
  484. /// <param name="dataTable">Data Table</param>
  485. /// <returns>Schema Name</returns>
  486. private string GetSchemaName(DataTable dataTable)
  487. {
  488. return GetExtendedProperty(dataTable, ExtendedProperties.DBSchemaName);
  489. }
  490. /// <summary>
  491. /// Gets the Table name for the given dataTable.
  492. /// </summary>
  493. /// <param name="dataTable">Data Table</param>
  494. /// <returns>Table Name</returns>
  495. private string GetTableName(DataTable dataTable)
  496. {
  497. string tableName = GetExtendedProperty(dataTable, ExtendedProperties.DBTableName);
  498. if (tableName == null || tableName.Length == 0)
  499. return dataTable.TableName;
  500. return tableName;
  501. }
  502. /// <summary>
  503. /// Get Extended Property from Object
  504. /// </summary>
  505. /// <param name="obj">Data Object</param>
  506. /// <param name="propName">Property Name</param>
  507. /// <returns>Property Value</returns>
  508. public static string GetExtendedProperty(object obj, string propName)
  509. {
  510. if (obj is System.Data.DataSet)
  511. {
  512. System.Data.DataSet dataSet = obj as System.Data.DataSet;
  513. if (dataSet.ExtendedProperties.Contains(propName))
  514. return (string)dataSet.ExtendedProperties[propName];
  515. return null;
  516. }
  517. if (obj is System.Data.DataTable)
  518. {
  519. System.Data.DataTable dataTable = obj as System.Data.DataTable;
  520. if (dataTable.ExtendedProperties.Contains(propName))
  521. return (string)dataTable.ExtendedProperties[propName];
  522. return null;
  523. }
  524. if (obj is System.Data.DataColumn)
  525. {
  526. System.Data.DataColumn dataColumn = obj as System.Data.DataColumn;
  527. if (dataColumn.ExtendedProperties.Contains(propName))
  528. return (string)dataColumn.ExtendedProperties[propName];
  529. return null;
  530. }
  531. if (obj is System.Data.DataRelation)
  532. {
  533. System.Data.DataRelation dataRelation = obj as System.Data.DataRelation;
  534. if (dataRelation.ExtendedProperties.Contains(propName))
  535. return (string)dataRelation.ExtendedProperties[propName];
  536. return null;
  537. }
  538. if (obj is System.Data.UniqueConstraint)
  539. {
  540. System.Data.UniqueConstraint uc = obj as System.Data.UniqueConstraint;
  541. if (uc.ExtendedProperties.Contains(propName))
  542. return (string)uc.ExtendedProperties[propName];
  543. return null;
  544. }
  545. if (obj is System.Data.ForeignKeyConstraint)
  546. {
  547. System.Data.ForeignKeyConstraint fkc = obj as System.Data.ForeignKeyConstraint;
  548. if (fkc.ExtendedProperties.Contains(propName))
  549. return (string)fkc.ExtendedProperties[propName];
  550. return null;
  551. }
  552. return null;
  553. }
  554. }
  555. /// <summary>
  556. /// Serves as an enumeration of Extended property names
  557. /// </summary>
  558. public class ExtendedProperties
  559. {
  560. private ExtendedProperties() { }
  561. public const string DataSourceID = "DataSourceID";
  562. public const string DBTableName = "DbTableName";
  563. public const string DBSchemaName = "DbSchemaName";
  564. public const string DBColumnName = "DbColumnName";
  565. public const string FriendlyName = "FriendlyName";
  566. public const string Description = "Description";
  567. public const string BatchID = "BatchID";
  568. public const string IsError = "IsError";
  569. public const string IsLogical = "IsLogical";
  570. public const string TableType = "TableType";
  571. public const string QueryDefinition = "QueryDefinition";
  572. public const string QueryBuilder = "QueryBuilder";
  573. public const string GenericQueryBuilderValue = "GenericQueryBuilder";
  574. public const string SpecificQueryBuilderValue = "SpecificQueryBuilder";
  575. public const string ComputedColumnExpression = "ComputedColumnExpression";
  576. public const string DataSize = "DataSize";
  577. public const string NewName = "NewName";
  578. public const string Regenerating = "Regenerating";
  579. public const string AllowGen = "AllowGen";
  580. public const string Project = "Project";
  581. public const string DSVTable = "DSVTable";
  582. public const string DSVColumn = "DSVColumn";
  583. public const string DSVRelation = "DSVRelation";
  584. public const string TrueValue = "True";
  585. public const string FalseValue = "False";
  586. public const string ViewTypeValue = "View";
  587. public const string TableTypeValue = "Table";
  588. }
  589. }