Sybase PowerDesigner是一个卓越的数据建模工具,它用Physical model描述特定数据库的数据模型,用Conceptual Model更抽象的描述数据库无关的数据模型。我们可以从概念模型入手进行建型,再根据不同的需要生成物理模型,进而生成库结构。也可以从现有数据库导出物理模型再转换成概念模型,然后转换成另一种数据库的物理模型......
在使用程序生成持久层的实体类和描述文件的时候,使用概念模型可以避免直接与不同的数据库打交道,当时代价是需要花点时间从数据库导出物理模型再转换成概念模型。下文提供分析Sybase CDM文件的代码,作为实体类生成工具的一个扩展。
首先是定义存储概念模型的类。
然后是分析CDM文件的工具类
![]()
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

{
public delegate void ProgressStatus( String message);

{

![]()
public event ProgressStatus StatusChanged;
{
{
StatusChanged( message );
}
}

#endregion

![]()
protected XmlDocument _cdmDocument;
protected XmlNamespaceManager _nsmgr;
#endregion

![]()
private ConceptualDataModel _model = new ConceptualDataModel();
#endregion
![]()
{
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
![]()
{
this.GetEntities();
this.GetDataItems();

{
Entity entity = (Entity)this._model.Entities[ entityOID ];
entity = this.GetEntityAttributes( entity );
}
{
Entity entity = (Entity)this._model.Entities[ entityOID ];
entity = this.GetEntityIdentifiers( entity );
}
this.GetEntityRelationships();
return this._model;
}

#endregion
![]()
{
this.OnStatusChanged("开始处理实体(entities)
");

XmlDocument xDoc = this._cdmDocument;

XmlNode entityNodes = xDoc.SelectSingleNode( "//c:Entities", this._nsmgr );
{
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)处理结束.");
}
{
this.OnStatusChanged("开始处理数据项(dataitems)
");

XmlNode dataItemNodes = this._cdmDocument.SelectSingleNode( "//c:DataItems", this._nsmgr );
{
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" );
{
dataitem.Length = Int32.Parse( this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Length" ) );
{
dataitem.Length = null;
}
{
dataitem.Precision = Int32.Parse( this.GetXmlNodeInnerTextAsString( dataItemNode, "a:Precision" ) );
{
dataitem.Precision = null;
}

String temp = dataitem.DataType;
{
temp = temp.Replace( dataitem.Length.Value.ToString(), String.Empty );
}
{
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)处理结束.");
}
{
this.OnStatusChanged("开始处理实体属性(attributes)
");
XmlNodeList attributeNodes = this._cdmDocument.SelectNodes(
String.Format( "//c:Entities/o:Entity[@Id='{0}']/c:Attributes/*", entity.ObjectID ), this._nsmgr );
{
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 &&
{
attr.IsMandatory = ( attributeNode.SelectSingleNode( "a:Mandatory", this._nsmgr ).InnerText == "1" );
{
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;

}
{
this.OnStatusChanged("开始处理实体键(Identifiers)
");

XmlNodeList identifierNodes = this._cdmDocument.SelectNodes(
String.Format( "//c:Entities/o:Entity[@Id='{0}']/c:Identifiers/*", entity.ObjectID ), this._nsmgr );
{
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 );

{
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;

}

{
this.OnStatusChanged("开始处理实体关系(relationships)
");
XmlNodeList relationshipNodes = this._cdmDocument.SelectNodes( "//c:Relationships/*", this._nsmgr );

{
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];

{
relationship.Entity1CardinalityMin = Int32.MaxValue;
{
relationship.Entity1CardinalityMin = Int32.Parse( e1cMin );
}
{
relationship.Entity1CardinalityMax = Int32.MaxValue;
{
relationship.Entity1CardinalityMax = Int32.Parse( e1cMax );
}
{
relationship.Entity2CardinalityMin = Int32.MaxValue;
{
relationship.Entity2CardinalityMin = Int32.Parse( e2cMin );
}
{
relationship.Entity2CardinalityMax = Int32.MaxValue;
{
relationship.Entity2CardinalityMax = Int32.Parse( e2cMax );
}

{
relationship.RelationshipType = EntityRelationshipTypes.OneToOne;
{
relationship.RelationshipType = EntityRelationshipTypes.ManyToMany;
{
relationship.RelationshipType = EntityRelationshipTypes.OneToMany;
{
relationship.RelationshipType = EntityRelationshipTypes.ManyToOne;
}

this._model.Relationships.Add( relationship.ObjectID, relationship );

entity1.FromEntityRelationships.Add( relationship );
entity2.ToEntityRelationships.Add( relationship );

EntityAttribute tempAttr = null;

{
case EntityRelationshipTypes.OneToOne :
{
tempAttr = (EntityAttribute)obj;
entity1.EntityAttributes.Add(tempAttr);
}
{
tempAttr = (EntityAttribute)obj;
entity2.EntityAttributes.Add(tempAttr);
}

entity1.Siblings.Add( entity2 );
entity2.Siblings.Add( entity1 );
break;
case EntityRelationshipTypes.OneToMany :
{
tempAttr = (EntityAttribute)obj;
entity2.EntityAttributes.Add(tempAttr);
}

entity1.ChildEntities.Add( entity2 );
entity2.Siblings.Add( entity1 );
break;
case EntityRelationshipTypes.ManyToOne :
{
tempAttr = (EntityAttribute)obj;
entity1.EntityAttributes.Add(tempAttr);
}

entity1.Siblings.Add( entity2 );
entity2.ChildEntities.Add( entity1 );
break;
case EntityRelationshipTypes.ManyToMany :
{
tempAttr = (EntityAttribute)obj;
entity1.EntityAttributes.Add(tempAttr);
}
{
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)处理结束.");
}
{
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 );
}


{
{
return 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();

{
String entityString = String.Empty;
Entity entity = (Entity)obj;

entityString += "Entity Code:" + entity.Code + ", Entity Name:" + entity.Name + "\r\n Attributes: ";
{
EntityAttribute attr = (EntityAttribute)attrObj;
entityString += attr.DataItem.Code + "[" + attr.IsMandatory.ToString() + "], ";
}
entityString += "\r\n Identifiers:";

{
EntityIdentifier iden = (EntityIdentifier)idenObj;
entityString += iden.Code + "[" + iden.IsPrimaryKey.ToString() + "], ";
}
entityString += "\r\n Relationships:";
{
EntityRelationship rel = (EntityRelationship)relObj;
entityString += rel.Code + "[" + rel.Entity1.Code + "], ";
}
entityString += "\r\n";
{
EntityRelationship rel = (EntityRelationship)relObj;
entityString += rel.Code + "[" + rel.Entity2.Code + "], ";
}
entityString += "\r\n";

this.textBox1.Text += "\r\n" + entityString;
相关文章:
-
2021-05-22
-
2021-06-06
-
2022-02-18
-
2022-12-23