XAF之数据库数据的预填充

         在设计XAF程序时有一个优点,可以脱离底层数据库的细节,不必了解到底是用的MSSQL或ORACL,只需要了解设计的Business Object,或者称之为XPObject,这些XPObject的类定义就对应了数据库的表定义,XPObject的每个持久化属性(字段)相应地对应了数据表的字段,一个XPObject对象也就对应了数据库表的一条记录,所有同类型XPObject的集合构成了一张数据表。另外,XPObject使用了AssociationAttribute特性标记来表示数据表的外键关系。而这就为我们预填充数据库带来了小小的麻烦:数据库中的外键字段可能是一个int类型,而在XPObject中该外键被表示为所引用表对应的XPObject类型,并以AssociationAttribute特性修饰,而当我们有大量预填充的数据时,我们通常是将这些数据放在独立的文件中(比如XML)而不是硬编码进程序,然后读取这些文件再填充数据库,现在问题来了,你的XML文档保存的引用外键若为5,那么怎样另XPObject保存该外键为一个对象呢?使用底层SQL语句显示不是理想的解决办法。这里,我写了一个专门的填充类DatabaseDump解决这个问题。

1.DatabaseDump使用方法

IList<Dictionary<string, string>> Records = new List<Dictionary<string, string>>();
//......将数据放入Records集合中......
DatabaseDump<MyPerson> dump = new DatabaseDump<MyPerson>(ObjectSpace);
dump.DumpTable(Records);
ObjectSpace.CommitChanges();
    这样,在软件/数据库设计时,需要做的仅仅是修改数据文件和XPObject的定义,另外可能要修改数据文件的读取程序。

    下面给出我的源码,功能很简单:

//类型T为所要填充的XPObject,完成填充后,需要手动ObjectSpace.CommitChanges()
    class DatabaseDump<T>
    {
        IObjectSpace ObjectSpace;
        public DatabaseDump(IObjectSpace ObjectSpace)
        {
            this.ObjectSpace = ObjectSpace;
        }
        //判断MyType类型中的PropertyName属性是否是一个外键
        private bool IsForeignKey(Type MyType, string ProperyName)
        {
            System.Reflection.PropertyInfo pi = MyType.GetProperty(ProperyName);
            bool IsAssociation = Attribute.GetCustomAttribute(pi, typeof(DevExpress.Xpo.AssociationAttribute)) is DevExpress.Xpo.AssociationAttribute;
            return IsAssociation && pi.PropertyType.IsSubclassOf(typeof(DevExpress.Xpo.XPBaseObject));
        }
        //填充表的记录,一条记录为一个Dictionary
        public void DumpTable(IList<Dictionary<string, string>> Records)
        {
            T obj=default(T);
            foreach (Dictionary<string, string> record in Records)
            {
                obj = ObjectSpace.CreateObject<T>();
                foreach (KeyValuePair<string, string> cell in record)
                {
                    if (IsForeignKey(typeof(T), cell.Key))
                    {
                        Type foreignType = typeof(T).GetProperty(cell.Key).PropertyType;
                        string foreignKeyName = ObjectSpace.GetKeyPropertyName(foreignType);
                        CriteriaOperator filter = new BinaryOperator(foreignKeyName, cell.Value, BinaryOperatorType.Equal);
                        object foreign = ObjectSpace.FindObject(foreignType, filter,true);
                        if(foreign!=null)
                            typeof(T).GetProperty(cell.Key).SetValue(obj, cell.Value, null);
                    }
                    else
                    {
                        typeof(T).GetProperty(cell.Key).SetValue(obj, cell.Value, null);
                    }
                }
            }
        }

    }

        需要说明一点的是,如果需要填充很多张表,而你的XPObject中主键标识为自增id([Key[true])或数据库端设置为自增,那么创建对象时赋值的ID可能和最终存储的ID是不一致的,所以最好是在所有数据填充完毕(都保存在ObjectSpace中)后,一起提交更改,避免错误。所以,我在类中使用了带bool参数的ObjectSpace.FindObject方法,否则是找不到未提交的记录的。

2.数据文件

         选择合适的格式保存数据文件,并编写对应的读取程序。我使用了简单的XML文件,并就近使用了C#的XmlTextReader解析文件,由于没有什么多余的信息,故这种无后退的读取方式也是无伤大雅的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值