• 【Oyster轻量框架】C# ORM 较灵活的轻量数据模型


    ORM 这个概念真的是我们开发人员的福音,避免了大量的重复劳动。

    而且做些适当的性能调整策略,效率是没有很多影响的,甚至比纯SQL的执行效率更高

    ,因为我们的应用通常都是给大量用户使用的,这样纯SQL的反而会造成某些瓶颈(具体就不说了,你懂的)。

    而现在流行的一些ORM框架的模型要么就是类似 Hibernate 的大量配置,要么就是大量使用 Attribute 的反射生成的。

    我参考了两类做了些调整,其实更类似Hibernate 的一个轻量级的框架,好的作品那么就值得以你自己的名字命名!他就叫Oyster!

    下面我首先分享一下我的数据模型的处理机制。

    C#:

     

    View Code
    1 /// <summary>
    2 /// Code By Tool 2011/3/1 20:23:32
    3 /// This is a Entity class
    4 ///
    5 /// </summary>
    6   [Serializable]
    7 public class AcHelp : Oyster.OrmEngine.IDataModel
    8 {
    9 public Type GetDataModelType()
    10 {
    11 return typeof(AcHelp);
    12 }
    13
    14 #region public - Property
    15 public System.Int32? HelpId { get; set; }
    16 public System.String Title { get; set; }
    17 public System.Object HelpContent { get; set; }
    18 public System.String Titletag { get; set; }
    19 public System.String Categorytag { get; set; }
    20 public System.Int32? SortNum { get; set; }
    21 public System.Int32? Status { get; set; }
    22 public System.DateTime? CreateTime { get; set; }
    23 public System.DateTime? LastChange { get; set; }
    24 public System.Int32? CreateUser { get; set; }
    25 public System.Int32? LastChangeUser { get; set; }
    26 public System.Int32? SortTag { get; set; }
    27 public System.Int32? HelpType { get; set; }
    28 #endregion
    29
    30 #region FieldsInfo
    31 public const string _HelpId = "HelpId";
    32 public const string _Title = "Title";
    33 public const string _HelpContent = "HelpContent";
    34 public const string _Titletag = "Titletag";
    35 public const string _Categorytag = "Categorytag";
    36 public const string _SortNum = "SortNum";
    37 public const string _Status = "Status";
    38 public const string _CreateTime = "CreateTime";
    39 public const string _LastChange = "LastChange";
    40 public const string _CreateUser = "CreateUser";
    41 public const string _LastChangeUser = "LastChangeUser";
    42 public const string _SortTag = "SortTag";
    43 public const string _HelpType = "HelpType";
    44 #endregion
    45 }

     

    他的配置文件XML:

     

    View Code
    1 <?xml version="1.0" encoding="utf-8" ?>
    2  <Class Name="Model.AcHelp,Model" QueryType="Table" TableName="AC_HELP">
    3 <Query>
    4 <![CDATA[
    5 SELECT
    6 HELP_ID
    7 ,TITLE
    8 ,HELP_CONTENT
    9 ,TITLETAG
    10 ,CATEGORYTAG
    11 ,SORT_NUM
    12 ,STATUS
    13 ,CREATE_TIME
    14 ,LAST_CHANGE
    15 ,CREATE_USER
    16 ,LAST_CHANGE_USER
    17 ,SORT_TAG
    18 ,HELP_TYPE
    19 FROM AC_HELP
    20 WHERE
    21 #OysterVal:Condition# #OysterVal:OrderBy#
    22  ]]>
    23 </Query>
    24 <Properties>
    25 <Propertie Name="HelpId" ColumnName="HELP_ID" IsUnique="true"/>
    26 <Propertie Name="Title" ColumnName="TITLE"/>
    27 <Propertie Name="HelpContent" ColumnName="HELP_CONTENT"/>
    28 <Propertie Name="Titletag" ColumnName="TITLETAG"/>
    29 <Propertie Name="Categorytag" ColumnName="CATEGORYTAG"/>
    30 <Propertie Name="SortNum" ColumnName="SORT_NUM"/>
    31 <Propertie Name="Status" ColumnName="STATUS"/>
    32 <Propertie Name="CreateTime" ColumnName="CREATE_TIME"/>
    33 <Propertie Name="LastChange" ColumnName="LAST_CHANGE"/>
    34 <Propertie Name="CreateUser" ColumnName="CREATE_USER"/>
    35 <Propertie Name="LastChangeUser" ColumnName="LAST_CHANGE_USER"/>
    36 <Propertie Name="SortTag" ColumnName="SORT_TAG"/>
    37 <Propertie Name="HelpType" ColumnName="HELP_TYPE"/>
    38 </Properties>
    39  </Class>

     

    ,这里其实就是对模型和数据表列做了对应,优化的部分就是加了Query语句的配置,因为Select 在系统中是非常重要的,

    通常是需要对其做些优化,比如指定索引等,所以提出来作为配置。

    然后就是在框架里使用时初始化配置的方法了,比较简单,其实我想说的是其实配置并不是很麻烦的事情。

     

    View Code
    1 using System;
    2  using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5 using System.IO;
    6 using System.Xml;
    7 using Oyster.Enums;
    8
    9 namespace Oyster.OrmEngine
    10 {
    11 public class ConfigEnginer
    12 {
    13 private static ConfigEnginer _instance;
    14 /// <summary>
    15 /// 配置信息操作引擎
    16 /// </summary>
    17 public static ConfigEnginer Instance
    18 {
    19 get
    20 {
    21 if (_instance == null)
    22 {
    23 _instance = new ConfigEnginer();
    24 }
    25 return _instance;
    26 }
    27 }
    28 #region 属性
    29 private DataModelCollection _dataModels;
    30 public DataModelCollection DataModels
    31 {
    32 get
    33 {
    34 if (_dataModels == null)
    35 {
    36 _dataModels = InitAllQuerySettings();
    37 }
    38 return _dataModels;
    39 }
    40 }
    41
    42 #endregion
    43
    44 #region 方法
    45
    46 public DataModelCollection InitAllQuerySettings()
    47 {
    48 DataModelCollection dics = new DataModelCollection();
    49 string path = System.AppDomain.CurrentDomain.BaseDirectory + "/OysterConfig/CLassList.xml";
    50 string pathdir = System.AppDomain.CurrentDomain.BaseDirectory;
    51 if (!File.Exists(path))
    52 {
    53 path = System.AppDomain.CurrentDomain.BaseDirectory + "/bin/OysterConfig/CLassList.xml";
    54 pathdir = System.AppDomain.CurrentDomain.BaseDirectory + "/bin";
    55 }
    56 if (File.Exists(path))
    57 {
    58 XmlDocument xdoc = new XmlDocument();
    59 var s = File.ReadAllText(path);
    60 xdoc.LoadXml(s);
    61
    62 var nodes = xdoc.GetElementsByTagName("Class");
    63 if (nodes != null)
    64 {
    65 foreach (XmlNode node in nodes)
    66 {
    67 string name = node.Attributes["Name"].Value;
    68 string classpath = node.Attributes["Path"].Value;
    69 if (!File.Exists(classpath))
    70 {
    71 classpath = pathdir + "/OysterConfig/" + classpath;
    72 }
    73 if (File.Exists(classpath))
    74 {
    75 QuerySetting qs = InitQuerySetting(File.ReadAllText(classpath));
    76 dics[qs.ClassType as Type] = qs;
    77 }
    78 }
    79 }
    80 }
    81
    82 return dics;
    83 }
    84
    85 public QuerySetting InitQuerySetting(string xml)
    86 {
    87 QuerySetting setting = null;
    88 XmlDocument xdoc = new XmlDocument();
    89 xdoc.LoadXml(xml);
    90 var classnode = xdoc.SelectSingleNode("Class");
    91 if (classnode != null)
    92 {
    93 string name = classnode.Attributes["Name"].Value;
    94 Type t = Type.GetType(name);
    95 if (t != null)
    96 {
    97 setting = new QuerySetting(t);
    98 setting.ClassName = t.FullName;
    99 setting.ClassType = t;
    100 }
    101 string querytype = classnode.Attributes["QueryType"].Value;
    102 switch (querytype)
    103 {
    104 case "Table":
    105 setting.QueryType = QueryType.Table;
    106 string tablename = classnode.Attributes["TableName"].Value;
    107 setting.TableName = tablename;
    108 break;
    109 case "Query":
    110 default:
    111 setting.QueryType = QueryType.Query;
    112 break;
    113 }
    114 var query = classnode.SelectSingleNode("Query");
    115 if (query != null)
    116 {
    117 setting.QueryString = query.InnerText;
    118 }
    119 XmlNodeList properties = classnode.SelectNodes("Properties/Propertie");
    120 var props = (setting.ClassType as Type).GetProperties();
    121 var dicpps = props.ToDictionary((pi) => { return pi.Name; });
    122 foreach (XmlNode p in properties)
    123 {
    124 ColumnSetting colsetting = new ColumnSetting();
    125 string pname = p.Attributes["Name"].Value;
    126 string pcolname = p.Attributes["ColumnName"].Value;
    127 if (p.Attributes["IsUnique"] != null && p.Attributes["IsUnique"].Value.Equals("true"))
    128 {
    129 colsetting.IsUnique = true;
    130 setting.UniqueColumn = colsetting;
    131 }
    132 colsetting.ColumnName = pcolname;
    133 colsetting.Property = pname;
    134 if (dicpps.ContainsKey(colsetting.Property))
    135 {
    136 colsetting.PropertyHandel = dicpps[colsetting.Property];
    137 colsetting.PropertyType = colsetting.PropertyHandel.PropertyType;
    138 }
    139 if (!setting.Columns.ContainsKey(pname))
    140 {
    141 setting.Columns.Add(pname, colsetting);
    142 }
    143 }
    144 }
    145 if (setting.UniqueColumn == null)
    146 {
    147 throw new Exception("plase set model xml on Propertie IsUnique=\"true\". ");
    148 }
    149
    150 return setting;
    151 }
    152
    153 #endregion
    154 }
    155 }

    这样我就是通过

    QuerySetting qs = ConfigEnginer.Instance.DataModels[model_type];

    快速获得数据模型的配置啦,这个配置里面还记录了每个类每个属性的 PropertyInfo PropertyHandel;

    这个对之后的数据绑定非常方便性能也非常好!~谢谢大家啦

    -------------------------------------------------- oyster:授人者方为师!
  • 相关阅读:
    已经二叉树的前序遍历和中序遍历 写出后序遍历算法
    Windows GVim
    PHP PDO
    Html5 Geolocation获取地理位置信息
    Vim字符编码/中文乱码详解
    Vim常用操作命令
    三列布局,左右宽度固定,中间一列随浏览器窗口变化宽度
    Html5 跨域通信
    Http 与 Socket 区别
    浏览器对比不应该成为月经帖或季度帖
  • 原文地址:https://www.cnblogs.com/touch/p/2017678.html
Copyright © 2020-2023  润新知