12.扩展字典(ExtensionDictionary)

愿你出走半生,归来仍是少年! 

环境:.NET FrameWork4.5、ObjectArx 2016 64bit、Entity Framework 6. 

        在10.扩展数据(XData)中我们讲到每个DbObject有一个XData对象可以存储数据,除此之外每个DbObject对象还有一个ExtensionDictionary(扩展字典)可以进行数据存储。

        在使用XData时为方便存取数据在一个实体上需要使用多个RegApplication进行区分,这个就要求在开发时进行提前的RegApp注册,这个比较麻烦;除此之外,据公司在CAD绘图的同事说,以前会有CAD中病毒导致扩展数据丢失的情况,所以可能扩展字典是一个更好的数据存储方式。

        除此之外XData数据存储是有上限的(16kb),然而扩展字典通过使用Xrecord(数据扩展记录)可达到2GB的数据存储量。

1.字典       

        扩展字典继承于DBDictionary 对象,DBDictionary 是CAD中存储非图形对象的容器。字典以两种方式存在,一种是存储在数据库中用来保存整个图纸的数据叫 NameDictionaries(命名对象字典),一种是储存在对象中用于保存对象的信息数据叫 ExtensionDictionary(对象扩展字典)。

2.扩展字典     

        扩展字典通常以键值对的方式存储数据,其键为文本格式,值为Xrecord(数据扩展记录)。每个DbObject对象在初始状态是并未拥有扩展字典的,需用通过CreateExtensionDictionary方法进行创建,创建后的字典可存储独属于该对象的数据。

        通过DBDictionary 对象的SetAt方法,可以将键以及值数据放入到字典中进场存储。下面以String类型的数据进行示例展示。

3.示例

3.1.DbObject扩展字典创建

        通过对自身扩展字典的性质进行判断,当为空时进行创建。

    /// <summary>
        /// 初始化扩展字典,有则跳过,没有创建
        /// </summary>
        /// <param name="dBObject"></param>
        private static void InitExtensionDictionary(this DBObject dBObject)
        {

            if (dBObject.ExtensionDictionary.IsNull)
            {
                dBObject.UpgradeOpen();

                dBObject.CreateExtensionDictionary();

                dBObject.DowngradeOpen();
            }
        }

3.2.新增键值对

        通过构建Xrecord(数据扩展记录)达到数据设置的效果。

   /// <summary>
        /// 向扩展字典内添加新的数据
        /// </summary>
        /// <param name="dBObject"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool AddDictionaryItem(this DBObject dBObject, string key, string value)
        {
            try
            {

                dBObject.InitExtensionDictionary();

                //写模式打开
                DBDictionary dic = dBObject.ExtensionDictionary.GetObject(OpenMode.ForWrite) as DBDictionary;

                //包含这个key就直接退出
                if (dic.Contains(key))
                {
                    return false;
                }

                //创建记录
                Xrecord xrec = new Xrecord();

                List<TypedValue> tempData = new List<TypedValue>();

                tempData.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, value));

                using (var rb = new ResultBuffer(tempData.ToArray()))
                {
                    xrec.Data = rb;
                }

                //添加到字典内
                dic.SetAt(key, xrec);

                //创建到库
                dBObject.Database.TransactionManager.AddNewlyCreatedDBObject(xrec, true);

                //关闭
                dic.DowngradeOpen();



                return true;



            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

3.3.修改/更新键值对

         修改字典中已有的键值对数据时,也是通过SetAt方法进行。但是由于数据为Xrecord(数据扩展记录)对象,其链式存在的情况,所以最好使用新的数据进行覆盖并移除原有的数据,不然容易出问题(类似数据保存失败、键直接丢掉等等)。

        在修改前还需要进行判断是否存在该键,为保证操作逻辑的正确,不存在的键也不可进行编辑。

 /// <summary>
        /// 设置字典中的指定Key的所有值
        /// </summary>
        /// <param name="dBObject"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool SetDictionaryItem(this DBObject dBObject, string key, bool value)
        {
            try
            {
                //不存在字典
                if (dBObject.ExtensionDictionary.IsNull)
                {
                    return false;
                }



                //写模式打开
                DBDictionary dic = dBObject.ExtensionDictionary.GetObject(OpenMode.ForWrite) as DBDictionary;

                //不包含这个key就直接退出
                if (!dic.Contains(key))
                {
                    return false;
                }


                ObjectId xrecordId = dic.GetAt(key);

                //创建记录
                Xrecord oldXrec = xrecordId.GetObject(OpenMode.ForWrite) as Xrecord;

                oldXrec.Erase(true);

                Xrecord xrec = new Xrecord();


                List<TypedValue> tempData = new List<TypedValue>();

                tempData.Add(new TypedValue((int)DxfCode.Bool, value));

                using (var rb = new ResultBuffer(tempData.ToArray()))
                {
                    xrec.Data = rb;
                }

                //添加到字典内
                dic.SetAt(key, xrec);

                //创建到库
                dBObject.Database.TransactionManager.AddNewlyCreatedDBObject(xrec, true);

                //关闭
                dic.DowngradeOpen();


                return true;



            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

3.4.获取指定键的数据

        通过GetAt方法可以获取到指定键的数据。

   /// <summary>
        /// 获取字典中的指定key的第一个值 
        /// </summary>
        /// <param name="dBObject"></param>
        /// <param name="key">键</param>
        /// <returns></returns>
        public static string GetDictionaryFirstString(this DBObject dBObject, string key)
        {
            try
            {
                //不存在字典
                if (dBObject.ExtensionDictionary.IsNull)
                {
                    return null;
                }



                DBDictionary dic = dBObject.ExtensionDictionary.GetObject(OpenMode.ForRead) as DBDictionary;

                //不包含键
                if (!dic.Contains(key))
                {
                    return null;
                }

                ObjectId xrecordId = dic.GetAt(key);

                Xrecord xrec = xrecordId.GetObject(OpenMode.ForRead) as Xrecord;

                string result = string.Empty;

                if (xrec != null && xrec.Data.AsArray().Length > 0)
                {

                    result = xrec.Data.AsArray()[0].Value.ToString();
                }

                return result;


            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

4.总结

        扩展字典通常以键值对的方式存储数据。由于Xrecord(数据扩展记录)对象的特殊性,使得扩展字典可以存储任意类型的数据。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

就是那个帕吉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值