Sybase Powerdesigner Conceptual Data Model 分析器
Sybase PowerDesigner是一个卓越的数据建模工具,它用Physical model描述特定数据库的数据模型,用Conceptual Model更抽象的描述数据库无关的数据模型。我们可以从概念模型入手进行建型,再根据不同的需要生成物理模型,进而生成库结构。也可以从现有数据库导出物理模型再转换成概念模型,然后转换成另一种数据库的物理模型......
在使用程序生成持久层的实体类和描述文件的时候,使用概念模型可以避免直接与不同的数据库打交道,当时代价是需要花点时间从数据库导出物理模型再转换成概念模型。下文提供分析Sybase CDM文件的代码,作为实体类生成工具的一个扩展。
首先是定义存储概念模型的类。
import namespaces#region import namespaces
using System;
using System.Collections;
using NBool = Nullables.NullableBoolean;
using NByte = Nullables.NullableByte;
using NDateTime = Nullables.NullableDateTime;
using NDecimal = Nullables.NullableDecimal;
using NDouble = Nullables.NullableDouble;
using NGuid = Nullables.NullableGuid;
using NInt16 = Nullables.NullableInt16;
using NInt32 = Nullables.NullableInt32;
using NInt64 = Nullables.NullableInt64;
using NSbyte = Nullables.NullableSByte;
using NSingle = Nullables.NullableSingle;
using Generator;
#endregion
namespace Generator.Utils.CDM {
/**//// <summary>
/// Entity 的摘要说明。
/// </summary>
public class Entity {
properties#region properties
protected int _id;
public int ID {
get {
return this._id;
}
set {
this._id = value;
}
}
protected string _code;
public string Code {
get {
return this._code;
}
set {
this._code = value;
}
}
protected string _name;
public string Name {
get {
return this._name;
}
set {
this._name = value;
}
}
protected string _comment;
public string Comment {
get {
return this._comment;
}
set {
this._comment = value;
}
}
protected string _objectID;
public string ObjectID {
get {
return this._objectID;
}
set {
this._objectID = value;
}
}
protected Entity _parentEntity;
public Entity ParentEntity {
get {
return this._parentEntity;
}
set {
this._parentEntity = value;
}
}
protected IList _entityAttributes = new ArrayList();
public IList EntityAttributes {
get {
return this._entityAttributes;
}
set {
this._entityAttributes = value;
}
}
protected IList _entityIdentifiers = new ArrayList();
public IList EntityIdentifiers {
get {
return this._entityIdentifiers;
}
set {
this._entityIdentifiers = value;
}
}
protected IList _fromEntityRelationships = new ArrayList();
public IList FromEntityRelationships {
get {
return this._fromEntityRelationships;
}
set {
this._fromEntityRelationships = value;
}
}
protected IList _toEntityRelationships = new ArrayList();
public IList ToEntityRelationships {
get {
return this._toEntityRelationships;
}
set {
this._toEntityRelationships = value;
}
}
public EntityIdentifier PrimaryIdentifier {
get {
foreach( object obj in this.EntityIdentifiers ) {
EntityIdentifier identifier = (EntityIdentifier)obj;
if( identifier.IsPrimaryKey.Value ) {
return identifier;
}
}
return null;
}
}
protected IList _childEntities = new ArrayList();
public IList ChildEntities {
get {
return this._childEntities;
}
}
protected IList _siblingEntities = new ArrayList();
public IList Siblings {
get {
return this._siblingEntities;
}
}
#endregion
public Entity() {
}
}
public class DataItem {
properties#region properties
protected string _objectID;
public string ObjectID {
get {
return this._objectID;
}
set {
this._objectID = value;
}
}
protected string _code;
public string Code {
get {
return this._code;
}
set {
this._code = value;
}
}
protected string _name;
public string Name {
get {
return this._name;
}
set {
this._name = value;
}
}
protected string _comment;
public string Comment {
get {
return this._comment;
}
set {
this._comment = value;
}
}
protected string _dataType;
public string DataType {
get {
return this._dataType;
}
set {
this._dataType = value;
}
}
protected NInt32 _length;
public NInt32 Length {
get {
return this._length;
}
set {
this._length = value;
}
}
protected NInt32 _precision;
public NInt32 Precision {
get {
return this._precision;
}
set {
this._precision = value;
}
}
protected string _defaultValue;
public string DefaultValue {
get {
return this._defaultValue;
}
set {
this._defaultValue = value;
}
}
protected string _minValue;
public string MinValue {
get {
return this._minValue;
}
set {
this._minValue = value;
}
}
protected string _maxValue;
public string MaxValue {
get {
return this._maxValue;
}
set {
this._maxValue = value;
}
}
protected IList _entityAttributes = new ArrayList();
public IList EntityAttributes {
get {
return this._entityAttributes;
}
set {
this._entityAttributes = value;
}
}
#endregion
public DataItem() {
}
}
public class EntityAttribute {
properties#region properties
protected string _objectID;
public string ObjectID {
get {
return this._objectID;
}
set {
this._objectID = value;
}
}
protected IList _entities = new ArrayList();
public IList Entities {
get {
return this._entities;
}
set {
this._entities = value;
}
}
protected DataItem _dataItem;
public DataItem DataItem {
get {
return this._dataItem;
}
set {
this._dataItem = value;
}
}
protected NBool _isMandatory;
public NBool IsMandatory {
get {
return this._isMandatory;
}
set {
this._isMandatory = value;
}
}
protected NBool _isSequence = false;
public NBool IsSequence {
get {
return this._isSequence;
}
set {
this._isSequence = value;
}
}
#endregion
public EntityAttribute() {
}
}
public class EntityIdentifier {
properties#region properties
protected string _code;
public string Code {
get {
return this._code;
}
set {
this._code = value;
}
}
protected string _name;
public string Name {
get {
return this._name;
}
set {
this._name = value;
}
}
protected NBool _isPrimaryKey;
public NBool IsPrimaryKey {
get {
return this._isPrimaryKey;
}
set {
this._isPrimaryKey = value;
}
}
protected string _objectID;
public string ObjectID {
get {
return this._objectID;
}
set {
this._objectID = value;
}
}
protected Entity _entity;
public Entity Entity {
get {
return this._entity;
}
set {
this._entity = value;
}
}
private IList _entityAttributes = new ArrayList();
public IList EntityAttributes {
get {
return this._entityAttributes;
}
set {
this._entityAttributes = value;
}
}
#endregion
public EntityIdentifier() {
}
}
public class EntityRelationship {
properties#region properties
protected string _objectID;
public string ObjectID {
get {
return this._objectID;
}
set {
this._objectID = value;
}
}
protected Entity _entity1;
public Entity Entity1 {
get {
return this._entity1;
}
set {
this._entity1 = value;
}
}
protected Entity _entity2;
public Entity Entity2 {
get {
return this._entity2;
}
set {
this._entity2 = value;
}
}
protected string _name;
public string Name {
get {
return this._name;
}
set {
this._name = value;
}
}
protected string _code;
public string Code {
get {
return this._code;
}
set {
this._code = value;
}
}
protected int _entity1CardinalityMin;
public int Entity1CardinalityMin {
get {
return this._entity1CardinalityMin;
}
set {
this._entity1CardinalityMin = value;
}
}
protected int _entity1CardinalityMax;
public int Entity1CardinalityMax {
get {
return this._entity1CardinalityMax;
}
set {
this._entity1CardinalityMax = value;
}
}
protected int _entity2CardinalityMin;
public int Entity2CardinalityMin {
get {
return this._entity2CardinalityMin;
}
set {
this._entity2CardinalityMin = value;
}
}
protected int _entity2CardinalityMax;
public int Entity2CardinalityMax {
get {
return this._entity2CardinalityMax;
}
set {
this._entity2CardinalityMax = value;
}
}
protected EntityRelationshipTypes _relationshipType;
public EntityRelationshipTypes RelationshipType {
get {
return this._relationshipType;
}
set {
this._relationshipType = value;
}
}
#endregion
public EntityRelationship() {
}
}
public class ConceptualDataModel {
properties#region properties
private IDictionary _entities = new Hashtable();
public IDictionary Entities {
get {
return this._entities;
}
set {
this._entities = value;
}
}
private IDictionary _dataItems = new Hashtable();
public IDictionary DataItems {
get {
return this._dataItems;
}
set {
this._dataItems = value;
}
}
private IDictionary _attributes = new Hashtable();
public IDictionary Attributes {
get {
return this._attributes;
}
set {
this._attributes = value;
}
}
private IDictionary _identifiers = new Hashtable();
public IDictionary Identifiers {
get {
return this._identifiers;
}
set {
this._identifiers = value;
}
}
private IDictionary _relationships = new Hashtable();
public IDictionary Relationships {
get {
return this._relationships;
}
set {
this._relationships = value;
}
}
#endregion
public ConceptualDataModel() {
//
// TODO: 在此处添加构造函数逻辑
//
}
}
}
using System;
using System.Collections;
using NBool = Nullables.NullableBoolean;
using NByte = Nullables.NullableByte;
using NDateTime = Nullables.NullableDateTime;
using NDecimal = Nullables.NullableDecimal;
using NDouble = Nullables.NullableDouble;
using NGuid = Nullables.NullableGuid;
using NInt16 = Nullables.NullableInt16;
using NInt32 = Nullables.NullableInt32;
using NInt64 = Nullables.NullableInt64;
using NSbyte = Nullables.NullableSByte;
using NSingle = Nullables.NullableSingle;
using Generator;
#endregion
namespace Generator.Utils.CDM {
/**//// <summary>
/// Entity 的摘要说明。
/// </summary>
public class Entity {
properties#region properties
protected int _id;
public int ID {
get {
return this._id;
}
set {
this._id = value;
}
}
protected string _code;
public string Code {
get {
return this._code;
}
set {
this._code = value;
}
}
protected string _name;
public string Name {
get {
return this._name;
}
set {
this._name = value;
}
}
protected string _comment;
public string Comment {
get {
return this._comment;
}
set {
this._comment = value;
}
}
protected string _objectID;
public string ObjectID {
get {
return this._objectID;
}
set {
this._objectID = value;
}
}
protected Entity _parentEntity;
public Entity ParentEntity {
get {
return this._parentEntity;
}
set {
this._parentEntity = value;
}
}
protected IList _entityAttributes = new ArrayList();
public IList EntityAttributes {
get {
return this._entityAttributes;
}
set {
this._entityAttributes = value;
}
}
protected IList _entityIdentifiers = new ArrayList();
public IList EntityIdentifiers {
get {
return this._entityIdentifiers;
}
set {
this._entityIdentifiers = value;
}
}
protected IList _fromEntityRelationships = new ArrayList();
public IList FromEntityRelationships {
get {
return this._fromEntityRelationships;
}
set {
this._fromEntityRelationships = value;
}
}
protected IList _toEntityRelationships = new ArrayList();
public IList ToEntityRelationships {
get {
return this._toEntityRelationships;
}
set {
this._toEntityRelationships = value;
}
}
public EntityIdentifier PrimaryIdentifier {
get {
foreach( object obj in this.EntityIdentifiers ) {
EntityIdentifier identifier = (EntityIdentifier)obj;
if( identifier.IsPrimaryKey.Value ) {
return identifier;
}
}
return null;
}
}
protected IList _childEntities = new ArrayList();
public IList ChildEntities {
get {
return this._childEntities;
}
}
protected IList _siblingEntities = new ArrayList();
public IList Siblings {
get {
return this._siblingEntities;
}
}
#endregion
public Entity() {
}
}
public class DataItem {
properties#region properties
protected string _objectID;
public string ObjectID {
get {
return this._objectID;
}
set {
this._objectID = value;
}
}
protected string _code;
public string Code {
get {
return this._code;
}
set {
this._code = value;
}
}
protected string _name;
public string Name {
get {
return this._name;
}
set {
this._name = value;
}
}
protected string _comment;
public string Comment {
get {
return this._comment;
}
set {
this._comment = value;
}
}
protected string _dataType;
public string DataType {
get {
return this._dataType;
}
set {
this._dataType = value;
}
}
protected NInt32 _length;
public NInt32 Length {
get {
return this._length;
}
set {
this._length = value;
}
}
protected NInt32 _precision;
public NInt32 Precision {
get {
return this._precision;
}
set {
this._precision = value;
}
}
protected string _defaultValue;
public string DefaultValue {
get {
return this._defaultValue;
}
set {
this._defaultValue = value;
}
}
protected string _minValue;
public string MinValue {
get {
return this._minValue;
}
set {
this._minValue = value;
}
}
protected string _maxValue;
public string MaxValue {
get {
return this._maxValue;
}
set {
this._maxValue = value;
}
}
protected IList _entityAttributes = new ArrayList();
public IList EntityAttributes {
get {
return this._entityAttributes;
}
set {
this._entityAttributes = value;
}
}
#endregion
public DataItem() {
}
}
public class EntityAttribute {
properties#region properties
protected string _objectID;
public string ObjectID {
get {
return this._objectID;
}
set {
this._objectID = value;
}
}
protected IList _entities = new ArrayList();
public IList Entities {
get {
return this._entities;
}
set {
this._entities = value;
}
}
protected DataItem _dataItem;
public DataItem DataItem {
get {
return this._dataItem;
}
set {
this._dataItem = value;
}
}
protected NBool _isMandatory;
public NBool IsMandatory {
get {
return this._isMandatory;
}
set {
this._isMandatory = value;
}
}
protected NBool _isSequence = false;
public NBool IsSequence {
get {
return this._isSequence;
}
set {
this._isSequence = value;
}
}
#endregion
public EntityAttribute() {
}
}
public class EntityIdentifier {
properties#region properties
protected string _code;
public string Code {
get {
return this._code;
}
set {
this._code = value;
}
}
protected string _name;
public string Name {
get {
return this._name;
}
set {
this._name = value;
}
}
protected NBool _isPrimaryKey;
public NBool IsPrimaryKey {
get {
return this._isPrimaryKey;
}
set {
this._isPrimaryKey = value;
}
}
protected string _objectID;
public string ObjectID {
get {
return this._objectID;
}
set {
this._objectID = value;
}
}
protected Entity _entity;
public Entity Entity {
get {
return this._entity;
}
set {
this._entity = value;
}
}
private IList _entityAttributes = new ArrayList();
public IList EntityAttributes {
get {
return this._entityAttributes;
}
set {
this._entityAttributes = value;
}
}
#endregion
public EntityIdentifier() {
}
}
public class EntityRelationship {
properties#region properties
protected string _objectID;
public string ObjectID {
get {
return this._objectID;
}
set {
this._objectID = value;
}
}
protected Entity _entity1;
public Entity Entity1 {
get {
return this._entity1;
}
set {
this._entity1 = value;
}
}
protected Entity _entity2;
public Entity Entity2 {
get {
return this._entity2;
}
set {
this._entity2 = value;
}
}
protected string _name;
public string Name {
get {
return this._name;
}
set {
this._name = value;
}
}
protected string _code;
public string Code {
get {
return this._code;
}
set {
this._code = value;
}
}
protected int _entity1CardinalityMin;
public int Entity1CardinalityMin {
get {
return this._entity1CardinalityMin;
}
set {
this._entity1CardinalityMin = value;
}
}
protected int _entity1CardinalityMax;
public int Entity1CardinalityMax {
get {
return this._entity1CardinalityMax;
}
set {
this._entity1CardinalityMax = value;
}
}
protected int _entity2CardinalityMin;
public int Entity2CardinalityMin {
get {
return this._entity2CardinalityMin;
}
set {
this._entity2CardinalityMin = value;
}
}
protected int _entity2CardinalityMax;
public int Entity2CardinalityMax {
get {
return this._entity2CardinalityMax;
}
set {
this._entity2CardinalityMax = value;
}
}
protected EntityRelationshipTypes _relationshipType;
public EntityRelationshipTypes RelationshipType {
get {
return this._relationshipType;
}
set {
this._relationshipType = value;
}
}
#endregion
public EntityRelationship() {
}
}
public class ConceptualDataModel {
properties#region properties
private IDictionary _entities = new Hashtable();
public IDictionary Entities {
get {
return this._entities;
}
set {
this._entities = value;
}
}
private IDictionary _dataItems = new Hashtable();
public IDictionary DataItems {
get {
return this._dataItems;
}
set {
this._dataItems = value;
}
}
private IDictionary _attributes = new Hashtable();
public IDictionary Attributes {
get {
return this._attributes;
}
set {
this._attributes = value;
}
}
private IDictionary _identifiers = new Hashtable();
public IDictionary Identifiers {
get {
return this._identifiers;
}
set {
this._identifiers = value;
}
}
private IDictionary _relationships = new Hashtable();
public IDictionary Relationships {
get {
return this._relationships;
}
set {
this._relationships = value;
}
}
#endregion
public ConceptualDataModel() {
//
// TODO: 在此处添加构造函数逻辑
//
}
}
}
然后是分析CDM文件的工具类
import namespaces#region import namespaces
using System;
using System.Xml;
using System.Collections;
using Generator.Utils.CDM;
using NBool = Nullables.NullableBoolean;
using NByte = Nullables.NullableByte;
using NDateTime = Nullables.NullableDateTime;
using NDecimal = Nullables.NullableDecimal;
using NDouble = Nullables.NullableDouble;
using NGuid = Nullables.NullableGuid;
using NInt16 = Nullables.NullableInt16;
using NInt32 = Nullables.NullableInt32;
using NInt64 = Nullables.NullableInt64;
using NSbyte = Nullables.NullableSByte;
using NSingle = Nullables.NullableSingle;
using System.Diagnostics;
#endregion
namespace Generator.Utils {
public delegate void ProgressStatus( String message);
public class SybaseCDMParser {
StatusChanged event#region StatusChanged event
public event ProgressStatus StatusChanged;
protected virtual void OnStatusChanged( String message ) {
if( StatusChanged != null ) {
StatusChanged( message );
}
}
#endregion
local variables#region local variables
protected XmlDocument _cdmDocument;
protected XmlNamespaceManager _nsmgr;
#endregion
properties#region properties
private ConceptualDataModel _model = new ConceptualDataModel();
#endregion
constructors#region constructors
public SybaseCDMParser( string conceptualDataModelFilePath ) {
this._cdmDocument = new XmlDocument();
this.OnStatusChanged( "正加载文件" );
this._cdmDocument.Load( conceptualDataModelFilePath );
this.OnStatusChanged("成功加载文件.");
this._nsmgr = new XmlNamespaceManager( this._cdmDocument.NameTable );
this._nsmgr.AddNamespace("c", "collection");
this._nsmgr.AddNamespace("o", "object");
this._nsmgr.AddNamespace("a", "attribute");
}
#endregion
public methods#region public methods
public virtual ConceptualDataModel processCDM() {
this.GetEntities();
this.GetDataItems();
foreach( object entityOID in this._model.Entities.Keys ) {
Entity entity = (Entity)this._model.Entities[ entityOID ];
entity = this.GetEntityAttributes( entity );
}
foreach( object entityOID in this._model.Entities.Keys ) {
Entity entity = (Entity)this._model.Entities[ entityOID ];
entity = this.GetEntityIdentifiers( entity );
}
this.GetEntityRelationships();
return this._model;
}
#endregion
helper methods#region helper methods
protected void GetEntities() {
this.OnStatusChanged("开始处理实体(entities)");
XmlDocument xDoc = this._cdmDocument;
XmlNode entityNodes = xDoc.SelectSingleNode( "//c:Entities", this._nsmgr );
foreach( XmlNode entityNode in entityNodes.ChildNodes ) {
Entity entity = new Entity();
entity.ObjectID = entityNode.Attributes.GetNamedItem( "Id" ).Value;
entity.Code = this.GetXmlNodeInnerTextAsString( entityNode, "a:Code" );
entity.Name = this.GetXmlNodeInnerTextAsString( entityNode, "a:Name" );
entity.Comment = this.GetXmlNodeInnerTextAsString( entityNode, "a:Comment" );
this._model.Entities.Add( entity.ObjectID, entity );
this.OnStatusChanged( entity.Code );
}
this.OnStatusChanged("实体(entities)处理结束.");
}
protected void GetDataItems() {
this.OnStatusChanged("开始处理数据项(dataitems)");
XmlNode dataItemNodes = this._cdmDocument.SelectSingleNode( "//c:DataItems", this._nsmgr );
foreach( XmlNode dataItemNode in dataItemNodes.ChildNodes ) {
DataItem dataitem = new DataItem();
dataitem.ObjectID = dataItemNode.Attributes.GetNamedItem( "Id" ).Value;
dataitem.Code = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Code" );
dataitem.Name = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Name" );
dataitem.Comment = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Comment" );
dataitem.DataType = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:DataType" );
dataitem.MinValue = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:LowValue" );
dataitem.MaxValue = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:HighValue" );
dataitem.DefaultValue = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:DefaultValue" );
try {
dataitem.Length = Int32.Parse( this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Length" ) );
} catch {
dataitem.Length = null;
}
try {
dataitem.Precision = Int32.Parse( this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Precision" ) );
} catch {
dataitem.Precision = null;
}
String temp = dataitem.DataType;
if( dataitem.Length != null ) {
temp = temp.Replace( dataitem.Length.Value.ToString(), String.Empty );
}
if( dataitem.Precision != null ) {
temp = temp.Replace( dataitem.Precision.Value.ToString(), String.Empty );
}
temp = temp.Replace( ",", String.Empty );
dataitem.DataType = temp;
this._model.DataItems.Add( dataitem.ObjectID, dataitem );
this.OnStatusChanged( dataitem.Code );
}
this.OnStatusChanged("数据项(dataitems)处理结束.");
}
protected Entity GetEntityAttributes(Entity entity ) {
this.OnStatusChanged("开始处理实体属性(attributes)");
XmlNodeList attributeNodes = this._cdmDocument.SelectNodes(
String.Format( "//c:Entities/o:Entity[@Id='{0}']/c:Attributes/*", entity.ObjectID ), this._nsmgr );
foreach( XmlNode attributeNode in attributeNodes ) {
EntityAttribute attr = new EntityAttribute();
DataItem dataItem = null;
String relDataItemObjectID = attributeNode.SelectSingleNode( "c:DataItem/o:DataItem/@Ref", this._nsmgr ).InnerText;
dataItem = (DataItem)this._model.DataItems[ relDataItemObjectID ];
attr.ObjectID = attributeNode.Attributes.GetNamedItem( "Id" ).Value;
attr.DataItem = dataItem;
if( attributeNode.SelectSingleNode( "a:Mandatory", this._nsmgr ) != null &&
attributeNode.SelectSingleNode( "a:Mandatory", this._nsmgr ).InnerText != null ) {
attr.IsMandatory = ( attributeNode.SelectSingleNode( "a:Mandatory", this._nsmgr ).InnerText == "1" );
} else {
attr.IsMandatory = false;
}
attr.IsSequence = dataItem.DataType.Trim().ToUpper().Equals( "NO".ToUpper() );
entity.EntityAttributes.Add( attr );
this._model.Attributes.Add( attr.ObjectID, attr );
this.OnStatusChanged(entity.Code + " - " + attr.DataItem.Code);
}
this.OnStatusChanged("实体属性(attributes)处理结束.");
return entity;
}
protected Entity GetEntityIdentifiers( Entity entity ) {
this.OnStatusChanged("开始处理实体键(Identifiers)");
XmlNodeList identifierNodes = this._cdmDocument.SelectNodes(
String.Format( "//c:Entities/o:Entity[@Id='{0}']/c:Identifiers/*", entity.ObjectID ), this._nsmgr );
foreach( XmlNode identifierNode in identifierNodes ) {
EntityIdentifier identifier = new EntityIdentifier();
EntityAttribute attr = null;
identifier.ObjectID = identifierNode.Attributes.GetNamedItem( "Id" ).Value;
identifier.Code = identifierNode.SelectSingleNode( "a:Code", this._nsmgr ).InnerText;
identifier.Name = identifierNode.SelectSingleNode( "a:Name", this._nsmgr ).InnerText;
identifier.Entity = entity;
XmlNodeList relAttrs = identifierNode.SelectNodes( "c:Identifier.Attributes/*", this._nsmgr );
foreach( XmlNode relAttr in relAttrs ) {
String relAttrObjectID = relAttr.Attributes.GetNamedItem( "Ref" ).Value;
attr = (EntityAttribute)this._model.Attributes[ relAttrObjectID ];
identifier.EntityAttributes.Add( attr );
}
identifier.IsPrimaryKey = this.IsPrimaryIdentifier( identifier.Entity.ObjectID, identifier.ObjectID );
entity.EntityIdentifiers.Add( identifier );
this._model.Identifiers.Add( identifier.ObjectID, identifier );
this.OnStatusChanged(entity.Code + " - " + identifier.Code);
}
this.OnStatusChanged("实体键(Identifiers)处理结束.");
return entity;
}
protected void GetEntityRelationships() {
this.OnStatusChanged("开始处理实体关系(relationships)");
XmlNodeList relationshipNodes = this._cdmDocument.SelectNodes( "//c:Relationships/*", this._nsmgr );
foreach( XmlNode relationshipNode in relationshipNodes ) {
EntityRelationship relationship = new EntityRelationship();
relationship.ObjectID = relationshipNode.Attributes.GetNamedItem( "Id" ).Value;
relationship.Code = relationshipNode.SelectSingleNode( "a:Code", this._nsmgr ).InnerText;
relationship.Name = relationshipNode.SelectSingleNode( "a:Name", this._nsmgr ).InnerText;
String entity1ObjectID = relationshipNode.SelectSingleNode( "c:Object1/o:Entity/@Ref", this._nsmgr ).InnerText;
String entity2ObjectID = relationshipNode.SelectSingleNode( "c:Object2/o:Entity/@Ref", this._nsmgr ).InnerText;
Entity entity1 = (Entity)this._model.Entities[ entity1ObjectID ];
Entity entity2 = (Entity)this._model.Entities[ entity2ObjectID ];
relationship.Entity1 = entity1;
relationship.Entity2 = entity2;
String e1Cardinality = relationshipNode.SelectSingleNode( "a:Entity2ToEntity1RoleCardinality", this._nsmgr ).InnerText;
String e2Cardinality = relationshipNode.SelectSingleNode( "a:Entity1ToEntity2RoleCardinality", this._nsmgr ).InnerText;
String e1cMin = e1Cardinality.Split( ',' )[0];
String e1cMax = e1Cardinality.Split( ',' )[1];
String e2cMin = e2Cardinality.Split( ',' )[0];
String e2cMax = e2Cardinality.Split( ',' )[1];
if( e1cMin.Equals( "n" ) ) {
relationship.Entity1CardinalityMin = Int32.MaxValue;
} else {
relationship.Entity1CardinalityMin = Int32.Parse( e1cMin );
}
if( e1cMax.Equals( "n" ) ) {
relationship.Entity1CardinalityMax = Int32.MaxValue;
} else {
relationship.Entity1CardinalityMax = Int32.Parse( e1cMax );
}
if( e2cMin.Equals( "n" ) ) {
relationship.Entity2CardinalityMin = Int32.MaxValue;
} else {
relationship.Entity2CardinalityMin = Int32.Parse( e2cMin );
}
if( e2cMax.Equals( "n" ) ) {
relationship.Entity2CardinalityMax = Int32.MaxValue;
} else {
relationship.Entity2CardinalityMax = Int32.Parse( e2cMax );
}
if( relationship.Entity1CardinalityMax == 1 && relationship.Entity2CardinalityMax == 1 ) {
relationship.RelationshipType = EntityRelationshipTypes.OneToOne;
} else if( relationship.Entity1CardinalityMax > 1 && relationship.Entity2CardinalityMax > 1 ) {
relationship.RelationshipType = EntityRelationshipTypes.ManyToMany;
} else if( relationship.Entity1CardinalityMax == 1 && relationship.Entity2CardinalityMin > 1 ){
relationship.RelationshipType = EntityRelationshipTypes.OneToMany;
} else {
relationship.RelationshipType = EntityRelationshipTypes.ManyToOne;
}
this._model.Relationships.Add( relationship.ObjectID, relationship );
entity1.FromEntityRelationships.Add( relationship );
entity2.ToEntityRelationships.Add( relationship );
EntityAttribute tempAttr = null;
switch( (EntityRelationshipTypes)relationship.RelationshipType ) {
case EntityRelationshipTypes.OneToOne :
foreach( object obj in entity2.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity1.EntityAttributes.Add(tempAttr);
}
foreach( object obj in entity1.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity2.EntityAttributes.Add(tempAttr);
}
entity1.Siblings.Add( entity2 );
entity2.Siblings.Add( entity1 );
break;
case EntityRelationshipTypes.OneToMany :
foreach( object obj in entity1.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity2.EntityAttributes.Add(tempAttr);
}
entity1.ChildEntities.Add( entity2 );
entity2.Siblings.Add( entity1 );
break;
case EntityRelationshipTypes.ManyToOne :
foreach( object obj in entity2.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity1.EntityAttributes.Add(tempAttr);
}
entity1.Siblings.Add( entity2 );
entity2.ChildEntities.Add( entity1 );
break;
case EntityRelationshipTypes.ManyToMany :
foreach( object obj in entity2.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity1.EntityAttributes.Add(tempAttr);
}
foreach( object obj in entity1.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity2.EntityAttributes.Add(tempAttr);
}
entity1.ChildEntities.Add( entity2 );
entity2.ChildEntities.Add( entity1 );
break;
default :
break;
}
this._model.Entities[ entity1ObjectID ] = entity1;
this._model.Entities[ entity2ObjectID ] = entity2;
this.OnStatusChanged( relationship.Code );
}
this.OnStatusChanged("实体关系(relationships)处理结束.");
}
private bool IsPrimaryIdentifier( String entityObjectID, String identifierObjectID ) {
XmlNode primary = this._cdmDocument.SelectSingleNode(
String.Format( "//c:Entities/o:Entity[@Id='{0}']/c:PrimaryIdentifier/o:Identifier[@Ref='{1}']", entityObjectID, identifierObjectID),
this._nsmgr );
return ( primary != null );
}
private String GetXmlNodeInnerTextAsString( XmlNode node, string xPathExp ) {
if( node == null ) {
return null;
}
if( node.SelectSingleNode( xPathExp, this._nsmgr ) == null ) {
return null;
}
return node.SelectSingleNode( xPathExp, this._nsmgr ).InnerText;
}
#endregion
}
}
using System;
using System.Xml;
using System.Collections;
using Generator.Utils.CDM;
using NBool = Nullables.NullableBoolean;
using NByte = Nullables.NullableByte;
using NDateTime = Nullables.NullableDateTime;
using NDecimal = Nullables.NullableDecimal;
using NDouble = Nullables.NullableDouble;
using NGuid = Nullables.NullableGuid;
using NInt16 = Nullables.NullableInt16;
using NInt32 = Nullables.NullableInt32;
using NInt64 = Nullables.NullableInt64;
using NSbyte = Nullables.NullableSByte;
using NSingle = Nullables.NullableSingle;
using System.Diagnostics;
#endregion
namespace Generator.Utils {
public delegate void ProgressStatus( String message);
public class SybaseCDMParser {
StatusChanged event#region StatusChanged event
public event ProgressStatus StatusChanged;
protected virtual void OnStatusChanged( String message ) {
if( StatusChanged != null ) {
StatusChanged( message );
}
}
#endregion
local variables#region local variables
protected XmlDocument _cdmDocument;
protected XmlNamespaceManager _nsmgr;
#endregion
properties#region properties
private ConceptualDataModel _model = new ConceptualDataModel();
#endregion
constructors#region constructors
public SybaseCDMParser( string conceptualDataModelFilePath ) {
this._cdmDocument = new XmlDocument();
this.OnStatusChanged( "正加载文件" );
this._cdmDocument.Load( conceptualDataModelFilePath );
this.OnStatusChanged("成功加载文件.");
this._nsmgr = new XmlNamespaceManager( this._cdmDocument.NameTable );
this._nsmgr.AddNamespace("c", "collection");
this._nsmgr.AddNamespace("o", "object");
this._nsmgr.AddNamespace("a", "attribute");
}
#endregion
public methods#region public methods
public virtual ConceptualDataModel processCDM() {
this.GetEntities();
this.GetDataItems();
foreach( object entityOID in this._model.Entities.Keys ) {
Entity entity = (Entity)this._model.Entities[ entityOID ];
entity = this.GetEntityAttributes( entity );
}
foreach( object entityOID in this._model.Entities.Keys ) {
Entity entity = (Entity)this._model.Entities[ entityOID ];
entity = this.GetEntityIdentifiers( entity );
}
this.GetEntityRelationships();
return this._model;
}
#endregion
helper methods#region helper methods
protected void GetEntities() {
this.OnStatusChanged("开始处理实体(entities)");
XmlDocument xDoc = this._cdmDocument;
XmlNode entityNodes = xDoc.SelectSingleNode( "//c:Entities", this._nsmgr );
foreach( XmlNode entityNode in entityNodes.ChildNodes ) {
Entity entity = new Entity();
entity.ObjectID = entityNode.Attributes.GetNamedItem( "Id" ).Value;
entity.Code = this.GetXmlNodeInnerTextAsString( entityNode, "a:Code" );
entity.Name = this.GetXmlNodeInnerTextAsString( entityNode, "a:Name" );
entity.Comment = this.GetXmlNodeInnerTextAsString( entityNode, "a:Comment" );
this._model.Entities.Add( entity.ObjectID, entity );
this.OnStatusChanged( entity.Code );
}
this.OnStatusChanged("实体(entities)处理结束.");
}
protected void GetDataItems() {
this.OnStatusChanged("开始处理数据项(dataitems)");
XmlNode dataItemNodes = this._cdmDocument.SelectSingleNode( "//c:DataItems", this._nsmgr );
foreach( XmlNode dataItemNode in dataItemNodes.ChildNodes ) {
DataItem dataitem = new DataItem();
dataitem.ObjectID = dataItemNode.Attributes.GetNamedItem( "Id" ).Value;
dataitem.Code = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Code" );
dataitem.Name = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Name" );
dataitem.Comment = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Comment" );
dataitem.DataType = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:DataType" );
dataitem.MinValue = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:LowValue" );
dataitem.MaxValue = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:HighValue" );
dataitem.DefaultValue = this.GetXmlNodeInnerTextAsString( dataItemNode, "a:DefaultValue" );
try {
dataitem.Length = Int32.Parse( this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Length" ) );
} catch {
dataitem.Length = null;
}
try {
dataitem.Precision = Int32.Parse( this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Precision" ) );
} catch {
dataitem.Precision = null;
}
String temp = dataitem.DataType;
if( dataitem.Length != null ) {
temp = temp.Replace( dataitem.Length.Value.ToString(), String.Empty );
}
if( dataitem.Precision != null ) {
temp = temp.Replace( dataitem.Precision.Value.ToString(), String.Empty );
}
temp = temp.Replace( ",", String.Empty );
dataitem.DataType = temp;
this._model.DataItems.Add( dataitem.ObjectID, dataitem );
this.OnStatusChanged( dataitem.Code );
}
this.OnStatusChanged("数据项(dataitems)处理结束.");
}
protected Entity GetEntityAttributes(Entity entity ) {
this.OnStatusChanged("开始处理实体属性(attributes)");
XmlNodeList attributeNodes = this._cdmDocument.SelectNodes(
String.Format( "//c:Entities/o:Entity[@Id='{0}']/c:Attributes/*", entity.ObjectID ), this._nsmgr );
foreach( XmlNode attributeNode in attributeNodes ) {
EntityAttribute attr = new EntityAttribute();
DataItem dataItem = null;
String relDataItemObjectID = attributeNode.SelectSingleNode( "c:DataItem/o:DataItem/@Ref", this._nsmgr ).InnerText;
dataItem = (DataItem)this._model.DataItems[ relDataItemObjectID ];
attr.ObjectID = attributeNode.Attributes.GetNamedItem( "Id" ).Value;
attr.DataItem = dataItem;
if( attributeNode.SelectSingleNode( "a:Mandatory", this._nsmgr ) != null &&
attributeNode.SelectSingleNode( "a:Mandatory", this._nsmgr ).InnerText != null ) {
attr.IsMandatory = ( attributeNode.SelectSingleNode( "a:Mandatory", this._nsmgr ).InnerText == "1" );
} else {
attr.IsMandatory = false;
}
attr.IsSequence = dataItem.DataType.Trim().ToUpper().Equals( "NO".ToUpper() );
entity.EntityAttributes.Add( attr );
this._model.Attributes.Add( attr.ObjectID, attr );
this.OnStatusChanged(entity.Code + " - " + attr.DataItem.Code);
}
this.OnStatusChanged("实体属性(attributes)处理结束.");
return entity;
}
protected Entity GetEntityIdentifiers( Entity entity ) {
this.OnStatusChanged("开始处理实体键(Identifiers)");
XmlNodeList identifierNodes = this._cdmDocument.SelectNodes(
String.Format( "//c:Entities/o:Entity[@Id='{0}']/c:Identifiers/*", entity.ObjectID ), this._nsmgr );
foreach( XmlNode identifierNode in identifierNodes ) {
EntityIdentifier identifier = new EntityIdentifier();
EntityAttribute attr = null;
identifier.ObjectID = identifierNode.Attributes.GetNamedItem( "Id" ).Value;
identifier.Code = identifierNode.SelectSingleNode( "a:Code", this._nsmgr ).InnerText;
identifier.Name = identifierNode.SelectSingleNode( "a:Name", this._nsmgr ).InnerText;
identifier.Entity = entity;
XmlNodeList relAttrs = identifierNode.SelectNodes( "c:Identifier.Attributes/*", this._nsmgr );
foreach( XmlNode relAttr in relAttrs ) {
String relAttrObjectID = relAttr.Attributes.GetNamedItem( "Ref" ).Value;
attr = (EntityAttribute)this._model.Attributes[ relAttrObjectID ];
identifier.EntityAttributes.Add( attr );
}
identifier.IsPrimaryKey = this.IsPrimaryIdentifier( identifier.Entity.ObjectID, identifier.ObjectID );
entity.EntityIdentifiers.Add( identifier );
this._model.Identifiers.Add( identifier.ObjectID, identifier );
this.OnStatusChanged(entity.Code + " - " + identifier.Code);
}
this.OnStatusChanged("实体键(Identifiers)处理结束.");
return entity;
}
protected void GetEntityRelationships() {
this.OnStatusChanged("开始处理实体关系(relationships)");
XmlNodeList relationshipNodes = this._cdmDocument.SelectNodes( "//c:Relationships/*", this._nsmgr );
foreach( XmlNode relationshipNode in relationshipNodes ) {
EntityRelationship relationship = new EntityRelationship();
relationship.ObjectID = relationshipNode.Attributes.GetNamedItem( "Id" ).Value;
relationship.Code = relationshipNode.SelectSingleNode( "a:Code", this._nsmgr ).InnerText;
relationship.Name = relationshipNode.SelectSingleNode( "a:Name", this._nsmgr ).InnerText;
String entity1ObjectID = relationshipNode.SelectSingleNode( "c:Object1/o:Entity/@Ref", this._nsmgr ).InnerText;
String entity2ObjectID = relationshipNode.SelectSingleNode( "c:Object2/o:Entity/@Ref", this._nsmgr ).InnerText;
Entity entity1 = (Entity)this._model.Entities[ entity1ObjectID ];
Entity entity2 = (Entity)this._model.Entities[ entity2ObjectID ];
relationship.Entity1 = entity1;
relationship.Entity2 = entity2;
String e1Cardinality = relationshipNode.SelectSingleNode( "a:Entity2ToEntity1RoleCardinality", this._nsmgr ).InnerText;
String e2Cardinality = relationshipNode.SelectSingleNode( "a:Entity1ToEntity2RoleCardinality", this._nsmgr ).InnerText;
String e1cMin = e1Cardinality.Split( ',' )[0];
String e1cMax = e1Cardinality.Split( ',' )[1];
String e2cMin = e2Cardinality.Split( ',' )[0];
String e2cMax = e2Cardinality.Split( ',' )[1];
if( e1cMin.Equals( "n" ) ) {
relationship.Entity1CardinalityMin = Int32.MaxValue;
} else {
relationship.Entity1CardinalityMin = Int32.Parse( e1cMin );
}
if( e1cMax.Equals( "n" ) ) {
relationship.Entity1CardinalityMax = Int32.MaxValue;
} else {
relationship.Entity1CardinalityMax = Int32.Parse( e1cMax );
}
if( e2cMin.Equals( "n" ) ) {
relationship.Entity2CardinalityMin = Int32.MaxValue;
} else {
relationship.Entity2CardinalityMin = Int32.Parse( e2cMin );
}
if( e2cMax.Equals( "n" ) ) {
relationship.Entity2CardinalityMax = Int32.MaxValue;
} else {
relationship.Entity2CardinalityMax = Int32.Parse( e2cMax );
}
if( relationship.Entity1CardinalityMax == 1 && relationship.Entity2CardinalityMax == 1 ) {
relationship.RelationshipType = EntityRelationshipTypes.OneToOne;
} else if( relationship.Entity1CardinalityMax > 1 && relationship.Entity2CardinalityMax > 1 ) {
relationship.RelationshipType = EntityRelationshipTypes.ManyToMany;
} else if( relationship.Entity1CardinalityMax == 1 && relationship.Entity2CardinalityMin > 1 ){
relationship.RelationshipType = EntityRelationshipTypes.OneToMany;
} else {
relationship.RelationshipType = EntityRelationshipTypes.ManyToOne;
}
this._model.Relationships.Add( relationship.ObjectID, relationship );
entity1.FromEntityRelationships.Add( relationship );
entity2.ToEntityRelationships.Add( relationship );
EntityAttribute tempAttr = null;
switch( (EntityRelationshipTypes)relationship.RelationshipType ) {
case EntityRelationshipTypes.OneToOne :
foreach( object obj in entity2.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity1.EntityAttributes.Add(tempAttr);
}
foreach( object obj in entity1.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity2.EntityAttributes.Add(tempAttr);
}
entity1.Siblings.Add( entity2 );
entity2.Siblings.Add( entity1 );
break;
case EntityRelationshipTypes.OneToMany :
foreach( object obj in entity1.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity2.EntityAttributes.Add(tempAttr);
}
entity1.ChildEntities.Add( entity2 );
entity2.Siblings.Add( entity1 );
break;
case EntityRelationshipTypes.ManyToOne :
foreach( object obj in entity2.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity1.EntityAttributes.Add(tempAttr);
}
entity1.Siblings.Add( entity2 );
entity2.ChildEntities.Add( entity1 );
break;
case EntityRelationshipTypes.ManyToMany :
foreach( object obj in entity2.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity1.EntityAttributes.Add(tempAttr);
}
foreach( object obj in entity1.PrimaryIdentifier.EntityAttributes ) {
tempAttr = (EntityAttribute)obj;
entity2.EntityAttributes.Add(tempAttr);
}
entity1.ChildEntities.Add( entity2 );
entity2.ChildEntities.Add( entity1 );
break;
default :
break;
}
this._model.Entities[ entity1ObjectID ] = entity1;
this._model.Entities[ entity2ObjectID ] = entity2;
this.OnStatusChanged( relationship.Code );
}
this.OnStatusChanged("实体关系(relationships)处理结束.");
}
private bool IsPrimaryIdentifier( String entityObjectID, String identifierObjectID ) {
XmlNode primary = this._cdmDocument.SelectSingleNode(
String.Format( "//c:Entities/o:Entity[@Id='{0}']/c:PrimaryIdentifier/o:Identifier[@Ref='{1}']", entityObjectID, identifierObjectID),
this._nsmgr );
return ( primary != null );
}
private String GetXmlNodeInnerTextAsString( XmlNode node, string xPathExp ) {
if( node == null ) {
return null;
}
if( node.SelectSingleNode( xPathExp, this._nsmgr ) == null ) {
return null;
}
return node.SelectSingleNode( xPathExp, this._nsmgr ).InnerText;
}
#endregion
}
}
最后是调用的示例代码:
SybaseCDMParser parser = new SybaseCDMParser( fileName );
parser.StatusChanged += new ProgressStatus(this.parser_StatusChanged);
ConceptualDataModel model = parser.processCDM();
foreach( object obj in model.Entities.Values ) {
String entityString = String.Empty;
Entity entity = (Entity)obj;
entityString += "Entity Code:" + entity.Code + ", Entity Name:" + entity.Name + "\r\n Attributes: ";
foreach( object attrObj in entity.EntityAttributes ) {
EntityAttribute attr = (EntityAttribute)attrObj;
entityString += attr.DataItem.Code + "[" + attr.IsMandatory.ToString() + "], ";
}
entityString += "\r\n Identifiers:";
foreach( object idenObj in entity.EntityIdentifiers ) {
EntityIdentifier iden = (EntityIdentifier)idenObj;
entityString += iden.Code + "[" + iden.IsPrimaryKey.ToString() + "], ";
}
entityString += "\r\n Relationships:";
foreach( object relObj in entity.FromEntityRelationships ) {
EntityRelationship rel = (EntityRelationship)relObj;
entityString += rel.Code + "[" + rel.Entity1.Code + "], ";
}
entityString += "\r\n";
foreach( object relObj in entity.ToEntityRelationships ) {
EntityRelationship rel = (EntityRelationship)relObj;
entityString += rel.Code + "[" + rel.Entity2.Code + "], ";
}
entityString += "\r\n";
this.textBox1.Text += "\r\n" + entityString;
parser.StatusChanged += new ProgressStatus(this.parser_StatusChanged);
ConceptualDataModel model = parser.processCDM();
foreach( object obj in model.Entities.Values ) {
String entityString = String.Empty;
Entity entity = (Entity)obj;
entityString += "Entity Code:" + entity.Code + ", Entity Name:" + entity.Name + "\r\n Attributes: ";
foreach( object attrObj in entity.EntityAttributes ) {
EntityAttribute attr = (EntityAttribute)attrObj;
entityString += attr.DataItem.Code + "[" + attr.IsMandatory.ToString() + "], ";
}
entityString += "\r\n Identifiers:";
foreach( object idenObj in entity.EntityIdentifiers ) {
EntityIdentifier iden = (EntityIdentifier)idenObj;
entityString += iden.Code + "[" + iden.IsPrimaryKey.ToString() + "], ";
}
entityString += "\r\n Relationships:";
foreach( object relObj in entity.FromEntityRelationships ) {
EntityRelationship rel = (EntityRelationship)relObj;
entityString += rel.Code + "[" + rel.Entity1.Code + "], ";
}
entityString += "\r\n";
foreach( object relObj in entity.ToEntityRelationships ) {
EntityRelationship rel = (EntityRelationship)relObj;
entityString += rel.Code + "[" + rel.Entity2.Code + "], ";
}
entityString += "\r\n";
this.textBox1.Text += "\r\n" + entityString;