现在的位置: 首页 > 综合 > 正文

dataset2anycode

2014年01月20日 ⁄ 综合 ⁄ 共 4152字 ⁄ 字号 评论关闭

MIS中DB是骨干,于是稍有不慎,一个项目的代码就过度依赖于DB的特性,失去了软件的独立性。当有一天打算换个DB类型时,发现不可替换。

DB核心在其建模,但DB不应该成为核心,核心是建模,而不是DB的模。

当然,更换DB类型不可行的原因不是模的问题,而是层的问题,太多与DB有关的代码夹杂到了业务层或者表示层去了。

于是我这样分层:

表示层、业务层、数据层、数据存取层、DB

DB只是一个用于保存数据的地方,MIS是功能驱动,而不是TABLE驱动。

VS也有建模工具,不过是依赖于DB进行的正向工程,把DB的模用DATASET表现出来。

但软件要保持其独立性,应该自己建模。在DATASET中建模,像VISIO那样,然后反向工程,从DATASET生成SQL,随后生成DB,坚决让DB只与存取层打交道,软件可以随时切换为其它DB类型,只不过是修改一下存取层而已。

DATASET建模的意义还在于可以生成任意类型的代码。有一款软件叫动软,作用是根据各类数据库模型生成项目,也支持自定义模板来生成代码。很早就关注,但最近开始使用后觉得不怎么方便,自己此前也用VS代码写过一款很僵化的代码生成工具,思想就是基于表生成代码。不过真的很僵化。

上一次使用词法后,觉得用词法是最终的解决办法。不过这一回还没有用到词法,词法的目的是让人脑做人脑做的事,电脑就让它去做电脑应该做的事吧。

先完成一个简单版本,模板的语法还在优化中。

以下是一个DATASET,两个表

<?xml version="1.0" encoding="utf-16"?>
<xs:schema id="DataSetTest" targetNamespace="http://tempuri.org/DataSetTest.xsd" xmlns:mstns="http://tempuri.org/DataSetTest.xsd" xmlns="http://tempuri.org/DataSetTest.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified">
  <xs:element name="DataSetTest" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="TestA">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="A" msdata:Caption="主键列" type="xs:int" />
              <xs:element name="B" msdata:Caption="字符列" minOccurs="0">
                <xs:simpleType>
                  <xs:restriction base="xs:string">
                    <xs:maxLength value="30" />
                  </xs:restriction>
                </xs:simpleType>
              </xs:element>
              <xs:element name="C" msdata:Caption="日期列" type="xs:dateTime" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="TestB">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="AA" msdata:Caption="主键列" type="xs:int" />
              <xs:element name="BB" msdata:Caption="字符列" minOccurs="0">
                <xs:simpleType>
                  <xs:restriction base="xs:string">
                    <xs:maxLength value="30" />
                  </xs:restriction>
                </xs:simpleType>
              </xs:element>
              <xs:element name="CC" msdata:Caption="日期列" type="xs:dateTime" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
    <xs:unique name="Constraint1" msdata:PrimaryKey="true">
      <xs:selector xpath=".//mstns:TestA" />
      <xs:field xpath="mstns:A" />
    </xs:unique>
    <xs:unique name="TestB_Constraint1" msdata:ConstraintName="Constraint1" msdata:PrimaryKey="true">
      <xs:selector xpath=".//mstns:TestB" />
      <xs:field xpath="mstns:AA" />
    </xs:unique>
  </xs:element>
</xs:schema>

利用SQL生成模板生成SQL,原理是使用解析器对模板进行解析,然后产生C#代码后再动态执行得到最终结果

//qoushui project template
code{.
	IDataSet2Sql DS2Sql =new DataSet2MSSql();
	foreach (System.Data.DataTable  table in ds.Tables)
	{
.}
create table @table.TableName 
( 
code{.
	for  (int colIndex=0;colIndex<table.Columns.Count;colIndex++)
	{
		 System.Data.DataColumn  column = table.Columns[colIndex];
.}
   @column.ColumnName  @DS2Sql.GetDataTypeString(column) @colIndex==table.Columns.Count-1?"":","        
code{.
        }  
.}
 ) ;
code{.
	}
.}

//qoushui project template
create table TestA 
( 
   A  int ,        
   B  nvarchar(30) ,        
   C  datetime         
 ) ;
create table TestB 
( 
   AA  int ,        
   BB  nvarchar(30) ,        
   CC  datetime         
 ) ;

利用另一个模板生成实体

//qoushui project template for 实体类
code{.
	IDataSet2Sql DS2Sql =new DataSet2MSSql();
	foreach (System.Data.DataTable  table in ds.Tables)
	{
.}
/// <summary>@table.TableName 
/// 自动生成的代码,请勿修改
/// </summary>
public partial class @table.TableName :I@table.TableName  {{ 
	#region 属性 
 
code{.
	for  (int colIndex=0;colIndex<table.Columns.Count;colIndex++)
	{
		 System.Data.DataColumn  column = table.Columns[colIndex];

.}
    /// <summary>
    /// @column.Caption
    /// </summary>
    /// <remarks>@column.Caption </remarks>
    public @column.DataType.ToString() @column.ColumnName  
    {{
        get;
        set;
    }}
    
code{.
        }  
.}
	#endregion

	#region 方法 
	#endregion
}}


code{.
	}
.}

//qoushui project template for 实体类
/// <summary>TestA 
/// 自动生成的代码,请勿修改
/// </summary>
public partial class TestA :ITestA  { 
	#region 属性 
 
    /// <summary>
    /// 主键列
    /// </summary>
    /// <remarks>主键列 </remarks>
    public System.Int32 A  
    {
        get;
        set;
    }
    
    /// <summary>
    /// 字符列
    /// </summary>
    /// <remarks>字符列 </remarks>
    public System.String B  
    {
        get;
        set;
    }
    
    /// <summary>
    /// 日期列
    /// </summary>
    /// <remarks>日期列 </remarks>
    public System.DateTime C  
    {
        get;
        set;
    }
    
	#endregion

	#region 方法 
	#endregion
}


/// <summary>TestB 
/// 自动生成的代码,请勿修改
/// </summary>
public partial class TestB :ITestB  { 
	#region 属性 
 
    /// <summary>
    /// 主键列
    /// </summary>
    /// <remarks>主键列 </remarks>
    public System.Int32 AA  
    {
        get;
        set;
    }
    
    /// <summary>
    /// 字符列
    /// </summary>
    /// <remarks>字符列 </remarks>
    public System.String BB  
    {
        get;
        set;
    }
    
    /// <summary>
    /// 日期列
    /// </summary>
    /// <remarks>日期列 </remarks>
    public System.DateTime CC  
    {
        get;
        set;
    }
    
	#endregion

	#region 方法 
	#endregion
}

抱歉!评论已关闭.