自动生成Info类的另外一个重要的原因在于,在一般的情况下,这些Info类没有可能一次就完全确定下来而不再修改,有了这个工具后,如果数据库结构有修改,则不必手工去更改代码,只需要重新运行一个Info类的代码生成器即可。
  为了让Info类适合一些逻辑要求,本Info类代码生成器需要手工进行一些必要的配置。如:一个Table中有DepartmentId字段,在一般情况下也需要将DepartmentName加到Info类中;一个Table有详细记录列表,则一般情况下也应该在该Info类中加一个IList类型的容纳记录列表的字段等。
  这些配置有些情况下是无法用代码自动完成的,所以必须手工配置。不过好在配置也并不复杂,而且一旦配置,后续就可以重复使用。其配置举例如下:
    1 <?xml version="1.0" encoding="utf-8" ?>
    2 <root>
    3     <tables>
    4         <item name="Department">
    5             <associations>
    6                 <item name="Departments" from="Department" alias="parent" source="DepartmentParent" nullable="true" delete="true" />
    7             </associations>
    8         </item>
    9         <item name="Employee">
   10             <additions>
   11                 <item name="DepartmentName" from="Department" source="DepartmentId" target="DepartmentId" />
   12                 <item name="PositionName" from="Position" source="PositionId" target="PositionId" />
   13                 <item name="EmployeeName" alias="ManagerName" table="Manager" from="Employee" source="EmployeeManager" target="EmployeeId" />
   14             </additions>
   15         </item>
   16     </tables>
   17     <removes>
   18         <item name="Table" />
   19     </removes>
   20 </root>
  对于该Table已经存在的字段来说,则不用进行任何配置,我们需要配置的,只是一些“异常”的字段。如附加字段(置于additions标识下)、关联记录(置于associations标识下)等。
  下面列举出主体部分的代码。其中处理较麻烦的部分在于有些字段可以为空,因此需要采用Nullable<>这样的范型类型。
    1     for (int i = 0; i < columns.Count; i++)
    2     {
    3         strContentes = strContentes + "        [DataMember]" + "\n";
    4 
    5         if (islinqs[i].ToString() == "True")
    6         {
    7             strContentes += string.Format("        [Column(Storage = \"_{0}\", DbType = \"{1}\", CanBeNull = {2})]" + "\n", columns[i].ToString(), dbtypes[i].ToString(), canbenulls[i].ToString());
    8         }
    9 
   10         if (canbenulls[i] != null && canbenulls[i].ToString() == "true" && types[i].ToString() != "String")
   11         {
   12             strContentes += string.Format("        public Nullable<{0}> {1}" + "\n", types[i].ToString(), columns[i].ToString());
   13         }
   14         else
   15         {
   16             strContentes += string.Format("        public {0} {1}" + "\n", types[i].ToString(), columns[i].ToString());
   17         }
   18 
   19         strContentes = strContentes + "        {" + "\n";
   20         strContentes += string.Format("            get {{ return this._{0}; }}" + "\n", columns[i].ToString());
   21         strContentes += string.Format("            set {{ this._{0} = value; }}" + "\n", columns[i].ToString());
   22         strContentes = strContentes + "        }" + "\n";
   23 
   24         if (i != columns.Count - 1)
   25         {
   26             strContentes = strContentes + "        " + "\n";
   27         }
   28     }
  至于XML的解析,可以采用反序列化的方法,直接一下子就把整个XML转化为类,这比起一步一步的解析XML来说,要容易得多了,具体请参考源代码。