zoukankan      html  css  js  c++  java
  • 关于ORM中只有XML没有映射实体的思考?期待大家的建议

    开篇

           很久没有写文章了,之前开了太多的系列,一方面是由于自己对于工作中的思考,另一方面是自己在业务时间中的对知识的总结,这里也是比较抱歉,因为之前开的系列,一直都是

    开,完整写完的不多,这里实在是对不住大家了,我也是想等过年期间好好的整理下,这些系列和思路,将要写的内容,都梳理清楚,然后在年后,将一一发布,完善如下的几个系列:

           1、Step by Step-构建自己的ORM系列-索引

           2、设计模式-系列索引

           3、系统架构师-基础到企业应用架构-系列索引

           4、云计算-从基础到应用架构系列索引

             当然,我期间可能会还有其他的相关文章会开启,但是我不会影响这些文章的进步,不然就太对不起大伙了,也希望大家多多提出自己的想法和意见,有了你们的帮助,我才能写的

    更完善。谢谢!

    摘要

             最近在项目中也是遇到如下的问题,也是查看了一些相应的资料,但是都没有很好的解决,问题如下:

             1、如何只通过XML文件来完成映射,当然这里的XML负责ORM中的数据库表列的相应信息。

             2、不想为数据库中的每个表都建立实体对象。

             3、能够仍然在界面使用的过程中方便的操作。

             4、还要考虑一些适应性和低耦合性方面的要求。

             有了上面的几个要求,经过思考,得出一下的几个思路,但是都不是理想的解决方案,还请大家看后以下的几个解决方案,给出意见。

    解决思路

                        上面也是给出了几个问题,我对这几个问题进行了整理和思考,得出下面的几个解决方案,但是都不是特别的理想,稍微的深入提出需求,就无法满足。

           一、通过NHibernate

                当然,Nhibernate本身已经提供了这方面的操作,我特别的举例说明如下,如果想详细的查看,请参考园子里面的高手博客《李永京》的。

                我这里将代码贴出:

                1、我们先看映射文件

        <class entity-name="Contract">
        <id name="Id" type="int">
            <generator class="Test"/>
        </id>
        <property name="Name" not-null="true" length="25" type="string"/>
        <property name="Pay" not-null="true"  type="decimal"/>
        <property name="CreateTime" not-null="true"  type="datetime"/>
        <property name="Description" not-null="true" length="200" type="string"/>
        </class>

                2、其他的配置,我就不详细说了,关于Nhibernate的配置。下面给出相应的示例代码:

        using (ISession session = new SessionFactory().OpenSession())
        {
            using (ITransaction trans = session.BeginTransaction())
            {
                IDictionary contract = new Hashtable();
                contract["Name"] = "合同名称";
                contract["Pay"] = 0.0M;//合同的金额
                contract["Description"] = "合同的描述信息";

                //第一个参数为映射中使用的实体名称,第二个参数为实例
                session.Save("Contract", contract);
                trans.Commit();
            }
        }

                上面给出的保存的代码,更新的代码雷同。给出查询代码:

        using (ISession session = new SessionFactory().OpenSession())
        {
            using (ITransaction trans = session.BeginTransaction())
            {
                IDictionary contract =(IDictionary) session.CreateQuery(“ from Contract where ContractID=:id”)

                                                       .Add(“id”,1);

                                                       .UniqueResult();

                session.Clear();

                trans.Commit();
            }
        }

                通过上面的代码,经过测试,的确能够将数据,通过Nhibernate提供的相应方法,完成访问。其他的相应的操作,我就不给出了,但是通过上面我们知道,我们没有通过创建相应的实体,我

    们就能完成映射的操作,的确不错,不过,这样的实现,的确有些不便。

                  二、通过自定义对象

                  这个自定义对象应该如何来做呢?自定义对象的思路如下:

                  image

                 下面来配合这个图给出示例代码,不一定可以运行,具体的公共对象类代码如下:

    public class CommonObject : IList
        {
            private IDictionary<string, Column> columns = null;
            public CommonObject()
            {
                columns = new Dictionary<string, Column>();
            }

            public CommonObject(int capacity)
            {
                columns = new Dictionary<string, Column>(capacity);
            }

            public Column Add(Column col)
            {
                this.columns.Add(col.Name,col);

                return col;
            }

            public bool Remove(Column col)
            {
                return this.columns.Remove(col.Name);
            }

            public Column this[string key]
            {
                get
                {
                    return this.columns[key];
                }
                set
                {
                    this.columns[key] = value;
                }
            }


            public int Add(object value)
            {
                throw new NotImplementedException();
            }

            public void Clear()
            {
                throw new NotImplementedException();
            }

            public bool Contains(object value)
            {
                throw new NotImplementedException();
            }

            public int IndexOf(object value)
            {
                throw new NotImplementedException();
            }

            public void Insert(int index, object value)
            {
                throw new NotImplementedException();
            }

            public bool IsFixedSize
            {
                get
                {
                    throw new NotImplementedException();
                }
            }

            public bool IsReadOnly
            {
                get
                {
                    throw new NotImplementedException();
                }
            }

            public void Remove(object value)
            {
                throw new NotImplementedException();
            }

            public void RemoveAt(int index)
            {
                throw new NotImplementedException();
            }

            public object this[int index]
            {
                get
                {
                    throw new NotImplementedException();
                }
                set
                {
                    throw new NotImplementedException();
                }
            }

            public void CopyTo(Array array, int index)
            {
                throw new NotImplementedException();
            }

            public int Count
            {
                get
                {
                    throw new NotImplementedException();
                }
            }

            public bool IsSynchronized
            {
                get
                {
                    throw new NotImplementedException();
                }
            }

            public object SyncRoot
            {
                get
                {
                    throw new NotImplementedException();
                }
            }

            public IEnumerator GetEnumerator()
            {
                throw new NotImplementedException();
            }
        }

               具体的代码上面已经给出,下面给出Column的示例代码:

    class Column
        {
            public string Name
            {
                get;
                set;
            }

            public object Value
            {
                get;
                set;
            }

            public System.Data.DbType DataType
            {
                get;
                set;
            }

            public string  DbColumnName
            {
                get;
                set;
            }

            public int Length
            {
                get;
                set;
            }

            public bool IsNull
            {
                get;
                set;
            }
        }

        当然上面给出的不是完整的,只是为了演示说明。这样就能完成与XML之间的映射,具体的访问的过程中也可以相对来说更友好一些。

          public void Test()
           {
               CommonObject comObj = CommonFactory<CommonObject>();

               comObj.Add(new Column());


               comObj["test"] = new Column();
           }

           private T CommonFactory<T>()
           {
               return (T)Activator.CreateInstance(typeof(T));
           }

           三、通过.NET 4.0中的动态类型来完成

                     下面给出实现的思路吧:

                      我们通过利用.NET4.0中的dynimic来定义一个内存中的实例,该实例是通过XML文件 中的配置的列属性来动态的创建,具体的代码如下:

    static void Main(string[] args)
            {
                dynamic obj=  GetTest();
                Console.WriteLine(obj.name);
                Console.WriteLine(obj.tt);
                System.Threading.Thread.Sleep(10000);
            }

            private static dynamic GetTest()
            {
                dynamic obj = new ExpandoObject();

                var person = obj as IDictionary<string, object>;

                person["name"] = "test";
                person["tt"] = "aaa";

                return obj;
            }

            通过上面的这个思路,我们就可以如下来做:

           private static dynamic GetTest1(string xmlFile)
            {
                dynamic obj = new ExpandoObject();

                var person = obj as IDictionary<string, object>;

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xmlFile);

                Property [] list = XMLHelper.GetPropertys(doc);
                foreach (Property property in list)
                {
                    person[property.Name] = property.Value;
                }

                person["name"] = "test";
                person["tt"] = "aaa";

                return obj;
            }

            这样就完成了,动态创建对象的过程,并且在应用可以之间使用动态创建的对象,但是有如下问题

            image

            通过上图中的描述,我想大家都知道,动态类型是动态运行时的编译,不是静态编译,必须在运行时才能解析出动态对象的属性信息,因此我们使用起来并不方便,所以我想到如下办法。

            image

            我思考完,发现如果要是可以实现这样的插件也就好了,当然目前的思路就到这,查看了相关职能感知的相关文件,但是没有发现API可以直接设置或者可以之间进行控制的方法。

    其他可行思路

              当然我上面只是给了几种可能可行的方案,但是不一定是合适的方案,还请大家多多指教和拍砖,如果您有好的思路或者实现方案,还请您提出来,多谢您的指

    教。

    后续

             下篇如果我有好的实现思路,我会给出完整的实现,当然如果没有思路,那就暂时写到这里,多谢大家的集思广益,可能我钻牛角尖了,也说不定。

  • CallHot

反馈文章质量,你可以通过快速通道评论:
查看全文
  • 相关阅读:
    Js 之xterm.js终端插件
    Mysql 之获取和修改注释
    Js 之codemirror文本编辑器
    Apicloud 之视频播放项目实战
    PHP 之极验验证插件
    PHP 之CI框架+GatewayWorker+AmazeUI仿微信聊天网页版
    PHP 之Html标签转义与反转义
    关于Vue中props的详解
    css特效之旋转音乐播放器
    微信小程序获取地理位置
  • 原文地址:https://www.cnblogs.com/hegezhou_hot/p/1941450.html
  • Copyright © 2011-2022 走看看