EF架构~XMLRepository仓储的实现~续(XAttribute方式)

回到目录

之前我写过关于XMLRepository仓储的实现的文章,主要是针对XElement方式的,对于XML的结构,一般来说有两种,一是使用节点方式的,我习惯称为XElement方式,别一种是属性方式的,我习惯称为XAttribute,这两种方式,我比较取向于后面的,好处就是更简洁,将C#里的类看作节点,而将C#里的属性看作是节点的每个特性(XAttribute),这种方式感觉更容易被人接受!

如果您还看不懂这两方式指的是什么,就看一下两种方式的XML举例吧

XElement方式

<User>
 <id>1</id>
 <name>zzl</name>
</User>

XAttribute方式

<User id="1" name="zzl" />

怎么样,第二种方式更简洁吧,但要注意,XAttribute方式书写时,需要为每个特性的值加双引号的,因为linq to xml认为每个XAttribute都是字符型的,在进行操作时,你可以根据实体类型进行转换的

下面看一下我为XAttribute方式进行封装的Repository吧

XML2Repository.cs源代码

    /// <summary>
    /// XML文件数据仓储
    /// XML结构为Attribute
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public class XML2Repository<TEntity> :
       IRepository<TEntity>
       where TEntity : XMLEntity, new()
    {
        XDocument _doc;
        string _filePath;
        static object lockObj = new object();
        public XML2Repository(string filePath)
        {
            _filePath = filePath;
            _doc = XDocument.Load(filePath);
        }
        public void Insert(TEntity item)
        {
            if (item == null)
                throw new ArgumentException("The database entity can not be null.");

            XElement db = new XElement(typeof(TEntity).Name);
            foreach (var member in item.GetType()
                                       .GetProperties()
                                       .Where(i => i.PropertyType.IsValueType
                                           || i.PropertyType == typeof(String)))
            {
                db.Add(new XAttribute(member.Name, member.GetValue(item, null)));
            }
            _doc.Root.Add(db);
            lock (lockObj)
            {
                _doc.Save(_filePath);
            }
        }

        public void Delete(TEntity item)
        {
            if (item == null)
                throw new ArgumentException("The database entity can not be null.");

            XElement xe = (from db in _doc.Root.Elements(typeof(TEntity).Name)
                           where db.Attribute("RootID").Value == item.RootID
                           select db).Single() as XElement;
            xe.Remove();
            lock (lockObj)
            {
                _doc.Save(_filePath);
            }
        }

        public void Update(TEntity item)
        {
            if (item == null)
                throw new ArgumentException("The database entity can not be null.");

            XElement xe = (from db in _doc.Root.Elements(typeof(TEntity).Name)
                           where db.Attribute("RootID").Value == item.RootID
                           select db).Single();
            try
            {
                foreach (var member in item.GetType()
                                           .GetProperties()
                                           .Where(i => i.PropertyType.IsValueType
                                               || i.PropertyType == typeof(String)))
                {
                    xe.SetAttributeValue(member.Name, member.GetValue(item, null));
                }
                lock (lockObj)
                {
                    _doc.Save(_filePath);
                }
            }

            catch
            {
                throw;
            }

        }

        public IQueryable<TEntity> GetModel()
        {
            IEnumerable<XElement> list = _doc.Root.Elements(typeof(TEntity).Name);
            IList<TEntity> returnList = new List<TEntity>();
            foreach (var item in list)
            {
                TEntity entity = new TEntity();
                foreach (var member in entity.GetType()
                                             .GetProperties()
                                             .Where(i => i.PropertyType.IsValueType
                                                 || i.PropertyType == typeof(String)))//只找简单类型的属性
                {
                    if (item.Attribute(member.Name) != null)
                        member.SetValue(entity, Convert.ChangeType(item.Attribute(member.Name).Value, member.PropertyType), null);//动态转换为指定类型
                }
                returnList.Add(entity);
            }
            return returnList.AsQueryable();
        }

        public TEntity Find(params object[] id)
        {
            return GetModel().FirstOrDefault(i => i.RootID == Convert.ToString(id[0]));
        }

        public void SetDbContext(IUnitOfWork unitOfWork)
        {
            throw new NotImplementedException();
        }
    }

至此,对于XML的仓储实现就已经完都讲完了,而对于其它仓储我也都在这前介绍过,其中包括EFRepsitory,LinqRepository,MemoryRepositoy,RedisRepository再加上今天的XMLRepository和XML2Repository一共六大仓储了,感觉已经可以写一篇

关于如何实现仓储的文章了,哈哈。

回到目录

时间: 2024-11-29 04:29:45

EF架构~XMLRepository仓储的实现~续(XAttribute方式)的相关文章

EF架构~基于EF数据层的实现

回到目录 之前写过关于实现一个完整的EF架构的文章,文章的阅读量也是满大的,自己很欣慰,但是,那篇文章是我2011年写的,所以,技术有些不成熟,所以今天把我的2014年写的EF底层架构公开一下,这个架构比2011年的有了很大程度的提高,主要在接口规范,查询规范上,并引入了排序功能,两步对完善了EF对数据的批量操作,可以说,这次的架构是很有看点的. 一 一个基础操作接口 /// <summary> /// 基础的数据操作规范 /// 与ORM架构无关 /// </summary> /

EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~终结~配置的优化和事务里读写的统一

回到目录 本讲是通过DbCommand拦截器来实现读写分离的最后一讲,对之前几篇文章做了一个优化,无论是程序可读性还是实用性上都有一个提升,在配置信息这块,去除了字符串方式的拼接,取而代之的是section数组,这样在修改配置时更加清晰了:而实用性上,彻底改变了读和写不能共用一个仓储对象的缺点,并且在一个事务里可以读写并存,并为了数据的一致性,使事务里的curd操作指向主库,这一点很重要! 前几篇文章的目录 EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~再续~添加对各只读服

EF架构~在Linq to Entity中使用日期函數

回到目录 眾所周知,在linq to entity的查询语句中,不允许出现ef不能识别的关键字,如Trim,Substring,TotalDays等.net里的关键字,在EF查询里都是不被支持的,它的原因可能是为了更好的提高查询的性能吧,毕竟,好的性能取决于你的程序标准,有了一个严格的标准,才能设计出好的程序来. 今天主要说一下,EF为日期方法留的一个后门,<后门>这个词大家在中国社会都应该知道了,顾名思义,就是反着原则走,你的原则对我没有用,哈哈!这东西有时候是有用的,因为在大的原则下,很可

EF架构~过滤导航属性等,拼接SQL字符串

拼接T-SQL串,并使它具有通用性 好处:与服务器建立一次连接,给服务器发一条SQL命令,即可实现 代码如下: 1 /// <summary> 2 /// 构建Insert语句串 3 /// 主键为自增时,如果主键值为0,我们将主键插入到SQL串中 4 /// </summary> 5 /// <typeparam name="TEntity"></typeparam> 6 /// <param name="entity&

EF架构~为EF DbContext生成的实体添加注释(T5模板应用)

相关文章系列 第八回 EF架构~将数据库注释添加导入到模型实体类中 第二十一回  EF架构~为EF DbContext生成的实体添加注释(T4模板应用) 第二十二回EF架构~为EF DbContext生成的实体添加注释(T5模板应用) 嗨,没法说,EF4的TT模版加上注释后,升级到EF5的TT模版后,注释就不通用了,所以,还得再研究一下,然后把操作方法再分享出来,没辙的微软! T4模版可能有些凌乱,这在T5模版里有了不错的改进,但我希望解决的问题在T5里并没有得到解决,那就是TT类文件自动得到E

第四十回 EF架构~LinqToEntity里实现left join的一对一与一对多

回到目录 对于linq to sql里实现left join我已经介绍过了,这篇文章的出现是由于最近在项目里遇到的一个问题,解决这个问题花了我不少时间,可能有2个小时,事件是这样的,对于两个表,它们是一对多关系,而需求是返回一个一对一的关系,并将最新的数据返回,这个很多同学都知道,可以使用inner join,但是,对于inner  join来说,当处理的是一对多关系时,它将会出现多条记录,这也是正常的:而它并不满足我们今天的需求,经过测试后,找到了解决这个问题的方法,下面看代码: 一对多关系

EF架构~EF异步改造之路~仓储接口的改造~续

回到目录 在写完仓储接口的改造改造后,总觉得有个代码的坏味道,这种味道源于它的DRP,即重复的代码太多了,即异步操作和同步操作其实只是在insert,update和delete上有所不同,获取数据的方法都是一样的,所以,我最后决定,将异步的接口进行改造,让它更加合理,方法后都加上Async的后缀,看上去也更像是个异步方法,呵. 改造后的异步接口 /// <summary> /// 异步操作 /// 基础的数据操作规范 /// 与ORM架构无关 /// </summary> ///

EF架构~通过EF6的DbCommand拦截器来实现数据库读写分离~续~添加事务机制

回到目录 上一讲中简单介绍了一个EF环境下通过DbCommand拦截器来实现SQLSERVER的读写分离,只是一个最简单的实现,而如果出现事务情况,还是会有一些问题的,因为在拦截器中我们手动开启了Connection链接,而在一个WEB请求时,如果你的一个变量即用到了read库又用到了write库,就会导致到sqlserver端的spid(system process id,系统进程ID,sqlserver里可能是某个数据库进程序的ID)发生变化 ,而对于这种变化,原本是本地的事务就会自动提升为

[原创]EF架构随心所欲打造属于你自己的DbModel

前言 我们都知道EF可以生成Dbmodel,系统生成的Model有时候并不是我们想要的,如何我们要生成自己的Model,那么久需要我们手动的去修改T4模版,T4是对“Text Template Transformation Toolkit”(4个T)的简称.如果你对T4不怎么了解可以去看蒋金楠(Artech)文章从数据到代码——基于T4的代码生成方式. 1.0先看看我们要达到的效果图吧 2.0首先我们来修改T4模版吧 打开T4模版,找到代码 WriteHeader(codeStringGener