1. public class RepositoryBase<T> : IRepository<T> where T : class

  RepositoryBase 是IRepository的一个 实例,泛型的作用是为特定的模型层提供标准的增删查改操作。

  1. protected XltAppDataContext DataContext;

  一个继承了DbContext的类(数据库上下文)↓↓↓↓↓↓↓↓↓

  1. public class XltAppDataContext : DbContext

  新增一个实体

  1. public object Add(T entity)
  2. {
  3. DataContext.Set<T>().Add(entity);
  4. return entity;
  5. }

  创建一个实体

  1. public T Create()
  2. {
  3. return DataContext.Set<T>().Create();
  4. }

  Create 和 Add  有什么区别呢,以下摘自MSDN?

  Create:Creates a new instance of an entity for the type of this set. Note that this instance is NOT added or attached to the set. The instance returned will be a proxy if the underlying context is configured to create proxies and the entity type meets the requirements for creating a proxy.

  Add:Adds the given entity to the context underlying the set in the Added state such that it will be inserted into the database when SaveChanges is called.

  今天我们来 最后分析一下这个基础 方法:

  

  1. public T CloneWithDynamicProxiesType(T modelObject)

  这个方法说的是“克隆,连带着代理类型”,下面我们来 分析一下这个方法的语句,今天不做深入分析。

  1. public T CloneWithDynamicProxiesType(T modelObject)
  2. {
  3. T dataModelProxy = DataContext.Set<T>().Create();
  4. Type dynamicType = typeof(T).GetType();
  5. var properties = dataModelProxy.GetType().GetProperties();
  6. //TODO: consider a better way to filter out all 'virual' properties of the model class
  7. foreach (var property in properties.Where(p => !p.PropertyType.Namespace.StartsWith("HP.XLT")))
  8. {
  9. try
  10. {
  11. //TODO: consider a better way to filter out all 'virual' properties of the model class
  12. var genArgType = property.PropertyType.GetGenericArguments().FirstOrDefault();
  13. if (genArgType== null || !genArgType.Namespace.StartsWith("HP.XLT"))
  14. {
  15. var value = property.GetValue(modelObject, null);
  16.  
  17. if (value == null)
  18. {
  19. continue;
  20. }
  21. property.SetValue(dataModelProxy, value);
  22. }
  23. }
  24. catch (Exception)
  25. {
  26. throw;
  27. }
  28. }
  29. return dataModelProxy;
  30. }

分析如下:

  下面这句话的意思应该是从DataContext中的固定类型中创建 一个实例,但是 这个实例是和具体的数据库无关的,也就是没有Attach or Set 到具体的表。

  1. T dataModelProxy = DataContext.Set<T>().Create();

  这个就是从泛型类中获取动态类型。

  1. Type dynamicType = typeof(T).GetType();

 下面是有关介绍:

  • typeof takes a type name (which you specify at compile time).
  • GetType gets the runtime type of an instance.

  相当于先得到这个类型的名字,然后再得到类型的实例,一个是编译时,一个是 运行时。

  

  下面的一句话,相当于利用反射从Type中获取Properties(属性)。

  1. var properties = dataModelProxy.GetType().GetProperties();

  下面 是一个foreach循环,它的意思是首先过滤 掉命名 空间 不以HP.XLT开头的Property

  1. foreach (var property in properties.Where(p => !p.PropertyType.Namespace.StartsWith("HP.XLT")))

  具体的关于GetProperties的介绍请参考Stackoverflow中的这个问题

今天 写到这里 ,明天继续 ------于2015/12/1日记录。

  又一天开始了,哈哈,今天继续。。。。

  我们 注意到了上面的GetProperties其实是得到了这个东西,也就是PropertyInfo:

  1. public PropertyInfo[] GetProperties();

  下面的语句:

  1. var genArgType = property.PropertyType.GetGenericArguments().FirstOrDefault();

  其实 本质上是得到一个Type,而这个Type是“每个”Property的Type,而GetGenericArguments()这个方法 是 得到了Type的一个数组,形如Type [].我们 可以通过如下的方法来使用,这是我写的:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace ConsoleApplicationCSharp
  8. {
  9. class Program
  10. {
  11. static void Main(string[] args)
  12. {
  13. Console.WriteLine("-------NonGenericType---------");
  14. IsGenericType(typeof(NonGenericType));
  15. Console.WriteLine("----------GenericType---------");
  16. IsGenericType(typeof(GenericType<>));
  17. Console.ReadLine();
  18. }
  19.  
  20. public static void IsGenericType(Type t)
  21. {
  22. if (t.IsGenericType)
  23. {
  24. // If this is a generic type, display the type arguments.
  25. //
  26. Type[] typeArguments = t.GetGenericArguments();
  27.  
  28. Console.WriteLine("\tList type arguments ({0}):",
  29. typeArguments.Length);
  30.  
  31. foreach (Type tParam in typeArguments)
  32. {
  33. // If this is a type parameter, display its
  34. // position.
  35. //
  36. if (tParam.IsGenericParameter)
  37. {
  38. Console.WriteLine("\t\t{0}\t(unassigned - parameter position {1})",
  39. tParam,
  40. tParam.GenericParameterPosition);
  41. }
  42. else
  43. {
  44. Console.WriteLine("\t\t{0}", tParam);
  45. }
  46. }
  47. }
  48. }
  49. }
  50.  
  51. public class NonGenericType
  52. {
  53. public string Name { get; set; }
  54. public int Age { get; set; }
  55. }
  56.  
  57. public class GenericType<T> where T : class
  58. {
  59. public string Name { get; set; }
  60. public int Age { get; set; }
  61.  
  62. public void Add(T t)
  63. {
  64.  
  65. }
  66.  
  67. }
  68.  
  69. }

  结果如下,我们 可以 看出只有使用了泛型类的,才会进方法,具体的参考上面的代码:

  下面 这句话 的意思 是,如果 没有参数或者参数的所属的类的命名空间不以XXX开头 的 时候,那么就,其实这个项目 所有的命名 空间都是有HP.XLT的,所以这句话的意思就是“找不到”相对应的参数。

  1. if (genArgType== null || !genArgType.Namespace.StartsWith("HP.XLT"))

  下面一句话,我觉得还是MSDN上面说得最好

  Returns the property value of a specified object with optional index values for indexed properties.

  意思就是返回特定的属性值---对于特定的对象:

  1. var value = property.GetValue(modelObject, null);

  下面展示了如果VALUE不为空,那么就把这个值赋给dataModelProxy,而这个dataModelProxy也是我们最终要 返回的实例,因为这里是一个基础方法,所以返回T。

  1. if (value == null)
  2. {
  3. continue;
  4. }
  5. property.SetValue(dataModelProxy, value);

  下面的代码,循环添加:  

  1. public virtual IEnumerable<T> Add(IEnumerable<T> entities)
  2. {
  3. foreach (var entity in entities)
  4. {
  5. Add(entity);
  6. }
  7.  
  8. return entities;
  9. }

  其中上面的方法 用到了单个 添加 ,代码 如下 :

  1. public object Add(T entity)
  2. {
  3. DataContext.Set<T>().Add(entity);
  4. return entity;
  5. }

  有些人可能对Add方法为什么要返回object有疑问,不能返回void吗?这里我说说我的理解 ,有2个 方面:

  • 已过期 :框架要考虑的是全部,如果你 返回的是一个VOID,那么如果想用这个实体,那么必然要重新去得到这个实体,这样浪费了时间和空间,所以返回VOID在 框架层面上是不好的。
  • 更新:返回VOID比 返回 OBJEECT要好,原因 很简单 ,没用到过。
  • 另一个问题是返回object好还是T好 ,可以明确的说,返回T好,因为T是一个泛型类,指向的是一个具体的类型,而如果 返回object,我还要进行强制类型转换才能得到 具体的实体。

  剩下的类似的方法如下:

  

  1. public T Create()
  2. {
  3. return DataContext.Set<T>().Create();
  4. }
  5.  
  6. public T Get(object id)
  7. {
  8. return DataContext.Set<T>().Find(id);
  9. }

    

  今天 写到这里 ,明天继续 ------于2015/12/2日记录。

  下面 的一个方法是 从DbContext中过滤数据

  1. public IEnumerable<T> FilterContext(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
  2. {
  3. return DataContext.Set<T>().Local.Where(predicate.Compile());
  4. }

  上面的代码 有几个知识点:

  1.Express<Func<T,bool>> 的用法

  2.Local永远不会去访问 数据库里的东西 ,它的目的是 把东西放在本地 缓存,这句话永远 用在查询 语句已经被 执行以后。

  下面的方式 是关于"Filter"的一个最重要的方法

  1. public IQueryable<T> Filter(System.Linq.Expressions.Expression<Func<T, bool>> expression, string includePath)
  2. {
  3. DbQuery<T> result = null;
  4.  
  5. if (!string.IsNullOrEmpty(includePath))
  6. {
  7. var includePathArray = includePath.Split(';');
  8.  
  9. foreach (var singlePath in includePathArray)
  10. {
  11. if (!string.IsNullOrEmpty(singlePath))
  12. {
  13. result = result == null ? DataContext.Set<T>().Include(singlePath) : result.Include(singlePath.Trim());
  14. }
  15. }
  16. }
  17. else
  18. {
  19. result = DataContext.Set<T>();
  20. }
  21.  
  22. return expression == null ? result.AsQueryable() : result.Where(expression).AsQueryable();
  23. }

  它是通过lambda表达式去进行过滤,DbQuery是一个 非泛型的Linq  to Entity实例对于DbContext来说。

  1. DbQuery<T> result = null;

  上面 这句话 先 判断IncludePath是否为空,至于Include是 干啥的呢?Include当中 包含了“属性的名称”,表示包含了此属性的所有的结果集。比如

  1. public ClassA Ainstance{get;set;} //这里面,属性的名称就是Ainstance

  注意ClassA是这里的一个 导航属性,也就是不能为基本数据类型,比如int,string什么的。

  下面 最后来 总结 一下 这个方法:

  下面再来看看一个特殊的方法:

  1. public void Update(T entity)
  2. {
  3. DataContext.Entry<T>(entity).State = EntityState.Modified;
  4. }

  这里的Entry,State是表示什么意思呢?下面的图可以揭开迷雾:

  其实不同的State对应了不同的状态,可以有不同的CRUD状态,上半部分的代码 和 下半部分的代码 其实 是 一个意思。

  下面介绍最后一个方法:

  1. public void Detach(T entity)
  2. {
  3. try //Catch 'invalid operation exception' - most likely cause: object is not attached
  4. {
  5. ((IObjectContextAdapter)DataContext).ObjectContext.Detach(entity);
  6. }
  7. catch (InvalidOperationException)
  8. { }
  9. }

  这么 写的目的是:不能有2个相同的KEY值在ObjectStateManager中,所以 需要把旧的实体从ORM中分离出去,这样才可以更新数据。

  大家 可以按转到定义按钮,去看看DbContext,得到如下结果,这证明了Dbcontext可以和IObjectContextAdapter进行强制 类型转换:

  MSDN上对于 ObjectContext.Detach的介绍相对 来说 比较 简单:从objectContext中移除相应的object.

  好了,这个文件讲解完毕----于2015-12-3日

RepositoryBase文件解析的更多相关文章

  1. CocosStudio文件解析工具CsdAnalysis

    起因 因为工作需要,所以需要使用CocosStudio来制作界面动画什么的.做完了发现需要找里边对象的时候会有很长一串代码,感觉不是很爽.之前写OC代码的时候可以吧程序中的对象指针跟编辑器中的对象相对 ...

  2. 通过正则表达式实现简单xml文件解析

    这是我通过正则表达式实现的xml文件解析工具,有些XHTML文件中包含特殊符号,暂时还无法正常使用. 设计思路:常见的xml文件都是单根树结构,工具的目的是通过递归的方式将整个文档树装载进一个Node ...

  3. 八、Android学习第七天——XML文件解析方法(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...

  4. phpcms V9 首页模板文件解析

    在了解了<phpcms V9 URL访问解析>之后,我们已经知道首页最终执行的是content模块下index控制器的init方法. 下面, 我们逐步分析过程如下: 第一.首页默认执行的是 ...

  5. (转)AVI文件格式解析+AVI文件解析工具

    AVI文件解析工具下载地址:http://download.csdn.net/detail/zjq634359531/7556659 AVI(Audio Video Interleaved的缩写)是一 ...

  6. itextSharp 附pdf文件解析

    一.PdfObject: pdf对象 ,有9种,对象是按照对象内涵来分的,如果按照对象的使用规则来说,对象又分为间接对象和直接对象.间接对象是PDF中最常用的对象,如前面对象集合里面的,所有对象都是间 ...

  7. 《热血传奇2》wix、wil文件解析Java实现

    在百度上搜索java+wil只有iteye上一篇有丁点儿内容,不过他说的是错的!或者说是不完整的,我个人认为我对于热血传奇客户端解析还是有一定研究的,请移步: <JMir——Java版热血传奇2 ...

  8. paper 37 : WINCE的BIB文件解析

    WINCE的BIB文件解析 BIB的全称为Binary Image Builder,在Wince编译过程中的最后MakeImage阶段会用到BIB文件,BIB文件的作用是指示构建系统如何构建二进制映像 ...

  9. 如何让你的Apache支持include文件解析和支持shtml的相关配置

    源地址:http://www.itokit.com/2011/0430/65992.html Apache支持include文件解析shtml首先要应该修改Apache配置文件httpd.conf . ...

随机推荐

  1. 黑云压城城欲摧 - 2016年iOS公开可利用漏洞总结

    黑云压城城欲摧 - 2016年iOS公开可利用漏洞总结 作者:蒸米,耀刺,黑雪 @ Team OverSky 0x00 序 iOS的安全性远比大家的想象中脆弱,除了没有公开的漏洞以外,还有很多已经公开 ...

  2. 线性数据结构之栈——Stack

    Linear data structures linear structures can be thought of as having two ends, whose items are order ...

  3. Android中手机录屏并转换GIF的两种方式

    之前在博文中为了更好的给大家演示APP的实现效果,本人了解学习了几种给手机录屏的方法,今天就给大家介绍两种我个人用的比较舒服的两种方法: (1)配置adb环境后,使用cmd命令将手机界面操作演示存为视 ...

  4. iOS---iOS10适配iOS当前所有系统的远程推送

    一.iOS推送通知简介 众所周知苹果的推送通知从iOS3开始出现, 每一年都会更新一些新的用法. 譬如iOS7出现的Silent remote notifications(远程静默推送), iOS8出 ...

  5. JavaScript function函数种类

    本篇主要介绍普通函数.匿名函数.闭包函数 目录 1. 普通函数:介绍普通函数的特性:同名覆盖.arguments对象.默认返回值等. 2. 匿名函数:介绍匿名函数的特性:变量匿名函数.无名称匿名函数. ...

  6. 开发者接入 基本配置 服务器配置 out.aspx

    页面代码: 前段为默认的,什么都不用写,后台如下: 即可 来自为知笔记(Wiz)

  7. CRM 数据密钥 忘记 解决方案

    UPDATE EmailServerProfile SET IncomingPassword=nullUPDATE EmailServerProfile SET OutgoingPassword=nu ...

  8. mysql删除重复记录语句的方法

    例如: id name value 1 a pp 2 a pp 3 b iii 4 b pp 5 b pp 6 c pp 7 c pp 8 c iii id是主键 要求得到这样的结果 id name ...

  9. linux下mono的安装与卸载

    我很遗憾的告诉你,这里没有安装,为什么标题里加入安装俩字呢,因为如果不加的话你会搜到这篇文章吗?哈哈!别气馁,这里会给你些安装的tips! 源码安装,git安装:建议安装路径如下,至于为什么,我也讲不 ...

  10. 关于HTML语义化的一些理解

    语义化这个词我想大家都看到了无数次,特别是在一些招聘广告上. 其实我自己也是,不过每次看到都觉得是那些招聘公司复制的,其实他们根本说不清语义化是什么,而且也根本不看重. 所以我一直也没把这东西当回事过 ...