RepositoryBase文件解析
public class RepositoryBase<T> : IRepository<T> where T : class
RepositoryBase 是IRepository的一个 实例,泛型的作用是为特定的模型层提供标准的增删查改操作。
protected XltAppDataContext DataContext;
一个继承了DbContext的类(数据库上下文)↓↓↓↓↓↓↓↓↓
public class XltAppDataContext : DbContext
新增一个实体
public object Add(T entity)
{
DataContext.Set<T>().Add(entity);
return entity;
}
创建一个实体
public T Create()
{
return DataContext.Set<T>().Create();
}
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.
今天我们来 最后分析一下这个基础 方法:
public T CloneWithDynamicProxiesType(T modelObject)
这个方法说的是“克隆,连带着代理类型”,下面我们来 分析一下这个方法的语句,今天不做深入分析。
public T CloneWithDynamicProxiesType(T modelObject)
{
T dataModelProxy = DataContext.Set<T>().Create();
Type dynamicType = typeof(T).GetType();
var properties = dataModelProxy.GetType().GetProperties();
//TODO: consider a better way to filter out all 'virual' properties of the model class
foreach (var property in properties.Where(p => !p.PropertyType.Namespace.StartsWith("HP.XLT")))
{
try
{
//TODO: consider a better way to filter out all 'virual' properties of the model class
var genArgType = property.PropertyType.GetGenericArguments().FirstOrDefault();
if (genArgType== null || !genArgType.Namespace.StartsWith("HP.XLT"))
{
var value = property.GetValue(modelObject, null); if (value == null)
{
continue;
}
property.SetValue(dataModelProxy, value);
}
}
catch (Exception)
{
throw;
}
}
return dataModelProxy;
}
分析如下:
下面这句话的意思应该是从DataContext中的固定类型中创建 一个实例,但是 这个实例是和具体的数据库无关的,也就是没有Attach or Set 到具体的表。
T dataModelProxy = DataContext.Set<T>().Create();
这个就是从泛型类中获取动态类型。
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(属性)。
var properties = dataModelProxy.GetType().GetProperties();
下面 是一个foreach循环,它的意思是首先过滤 掉命名 空间 不以HP.XLT开头的Property
foreach (var property in properties.Where(p => !p.PropertyType.Namespace.StartsWith("HP.XLT")))
具体的关于GetProperties的介绍请参考Stackoverflow中的这个问题。
今天 写到这里 ,明天继续 ------于2015/12/1日记录。
又一天开始了,哈哈,今天继续。。。。
我们 注意到了上面的GetProperties其实是得到了这个东西,也就是PropertyInfo:
public PropertyInfo[] GetProperties();
下面的语句:
var genArgType = property.PropertyType.GetGenericArguments().FirstOrDefault();
其实 本质上是得到一个Type,而这个Type是“每个”Property的Type,而GetGenericArguments()这个方法 是 得到了Type的一个数组,形如Type [].我们 可以通过如下的方法来使用,这是我写的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ConsoleApplicationCSharp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("-------NonGenericType---------");
IsGenericType(typeof(NonGenericType));
Console.WriteLine("----------GenericType---------");
IsGenericType(typeof(GenericType<>));
Console.ReadLine();
} public static void IsGenericType(Type t)
{
if (t.IsGenericType)
{
// If this is a generic type, display the type arguments.
//
Type[] typeArguments = t.GetGenericArguments(); Console.WriteLine("\tList type arguments ({0}):",
typeArguments.Length); foreach (Type tParam in typeArguments)
{
// If this is a type parameter, display its
// position.
//
if (tParam.IsGenericParameter)
{
Console.WriteLine("\t\t{0}\t(unassigned - parameter position {1})",
tParam,
tParam.GenericParameterPosition);
}
else
{
Console.WriteLine("\t\t{0}", tParam);
}
}
}
}
} public class NonGenericType
{
public string Name { get; set; }
public int Age { get; set; }
} public class GenericType<T> where T : class
{
public string Name { get; set; }
public int Age { get; set; } public void Add(T t)
{ } } }
结果如下,我们 可以 看出只有使用了泛型类的,才会进方法,具体的参考上面的代码:
下面 这句话 的意思 是,如果 没有参数或者参数的所属的类的命名空间不以XXX开头 的 时候,那么就,其实这个项目 所有的命名 空间都是有HP.XLT的,所以这句话的意思就是“找不到”相对应的参数。
if (genArgType== null || !genArgType.Namespace.StartsWith("HP.XLT"))
下面一句话,我觉得还是MSDN上面说得最好
Returns the property value of a specified object with optional index values for indexed properties.
意思就是返回特定的属性值---对于特定的对象:
var value = property.GetValue(modelObject, null);
下面展示了如果VALUE不为空,那么就把这个值赋给dataModelProxy,而这个dataModelProxy也是我们最终要 返回的实例,因为这里是一个基础方法,所以返回T。
if (value == null)
{
continue;
}
property.SetValue(dataModelProxy, value);
下面的代码,循环添加:
public virtual IEnumerable<T> Add(IEnumerable<T> entities)
{
foreach (var entity in entities)
{
Add(entity);
} return entities;
}
其中上面的方法 用到了单个 添加 ,代码 如下 :
public object Add(T entity)
{
DataContext.Set<T>().Add(entity);
return entity;
}
有些人可能对Add方法为什么要返回object有疑问,不能返回void吗?这里我说说我的理解 ,有2个 方面:
- 已过期 :框架要考虑的是全部,如果你 返回的是一个VOID,那么如果想用这个实体,那么必然要重新去得到这个实体,这样浪费了时间和空间,所以返回VOID在 框架层面上是不好的。
- 更新:返回VOID比 返回 OBJEECT要好,原因 很简单 ,没用到过。
- 另一个问题是返回object好还是T好 ,可以明确的说,返回T好,因为T是一个泛型类,指向的是一个具体的类型,而如果 返回object,我还要进行强制类型转换才能得到 具体的实体。
剩下的类似的方法如下:
public T Create()
{
return DataContext.Set<T>().Create();
} public T Get(object id)
{
return DataContext.Set<T>().Find(id);
}
今天 写到这里 ,明天继续 ------于2015/12/2日记录。
下面 的一个方法是 从DbContext中过滤数据
public IEnumerable<T> FilterContext(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
return DataContext.Set<T>().Local.Where(predicate.Compile());
}
上面的代码 有几个知识点:
2.Local永远不会去访问 数据库里的东西 ,它的目的是 把东西放在本地 缓存,这句话永远 用在查询 语句已经被 执行以后。
下面的方式 是关于"Filter"的一个最重要的方法
public IQueryable<T> Filter(System.Linq.Expressions.Expression<Func<T, bool>> expression, string includePath)
{
DbQuery<T> result = null; if (!string.IsNullOrEmpty(includePath))
{
var includePathArray = includePath.Split(';'); foreach (var singlePath in includePathArray)
{
if (!string.IsNullOrEmpty(singlePath))
{
result = result == null ? DataContext.Set<T>().Include(singlePath) : result.Include(singlePath.Trim());
}
}
}
else
{
result = DataContext.Set<T>();
} return expression == null ? result.AsQueryable() : result.Where(expression).AsQueryable();
}
它是通过lambda表达式去进行过滤,DbQuery是一个 非泛型的Linq to Entity实例对于DbContext来说。
DbQuery<T> result = null;
上面 这句话 先 判断IncludePath是否为空,至于Include是 干啥的呢?Include当中 包含了“属性的名称”,表示包含了此属性的所有的结果集。比如
public ClassA Ainstance{get;set;} //这里面,属性的名称就是Ainstance
注意ClassA是这里的一个 导航属性,也就是不能为基本数据类型,比如int,string什么的。
下面 最后来 总结 一下 这个方法:
下面再来看看一个特殊的方法:
public void Update(T entity)
{
DataContext.Entry<T>(entity).State = EntityState.Modified;
}
这里的Entry,State是表示什么意思呢?下面的图可以揭开迷雾:
其实不同的State对应了不同的状态,可以有不同的CRUD状态,上半部分的代码 和 下半部分的代码 其实 是 一个意思。
下面介绍最后一个方法:
public void Detach(T entity)
{
try //Catch 'invalid operation exception' - most likely cause: object is not attached
{
((IObjectContextAdapter)DataContext).ObjectContext.Detach(entity);
}
catch (InvalidOperationException)
{ }
}
这么 写的目的是:不能有2个相同的KEY值在ObjectStateManager中,所以 需要把旧的实体从ORM中分离出去,这样才可以更新数据。
大家 可以按转到定义按钮,去看看DbContext,得到如下结果,这证明了Dbcontext可以和IObjectContextAdapter进行强制 类型转换:
MSDN上对于 ObjectContext.Detach的介绍相对 来说 比较 简单:从objectContext中移除相应的object.
好了,这个文件讲解完毕----于2015-12-3日。
RepositoryBase文件解析的更多相关文章
- CocosStudio文件解析工具CsdAnalysis
起因 因为工作需要,所以需要使用CocosStudio来制作界面动画什么的.做完了发现需要找里边对象的时候会有很长一串代码,感觉不是很爽.之前写OC代码的时候可以吧程序中的对象指针跟编辑器中的对象相对 ...
- 通过正则表达式实现简单xml文件解析
这是我通过正则表达式实现的xml文件解析工具,有些XHTML文件中包含特殊符号,暂时还无法正常使用. 设计思路:常见的xml文件都是单根树结构,工具的目的是通过递归的方式将整个文档树装载进一个Node ...
- 八、Android学习第七天——XML文件解析方法(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...
- phpcms V9 首页模板文件解析
在了解了<phpcms V9 URL访问解析>之后,我们已经知道首页最终执行的是content模块下index控制器的init方法. 下面, 我们逐步分析过程如下: 第一.首页默认执行的是 ...
- (转)AVI文件格式解析+AVI文件解析工具
AVI文件解析工具下载地址:http://download.csdn.net/detail/zjq634359531/7556659 AVI(Audio Video Interleaved的缩写)是一 ...
- itextSharp 附pdf文件解析
一.PdfObject: pdf对象 ,有9种,对象是按照对象内涵来分的,如果按照对象的使用规则来说,对象又分为间接对象和直接对象.间接对象是PDF中最常用的对象,如前面对象集合里面的,所有对象都是间 ...
- 《热血传奇2》wix、wil文件解析Java实现
在百度上搜索java+wil只有iteye上一篇有丁点儿内容,不过他说的是错的!或者说是不完整的,我个人认为我对于热血传奇客户端解析还是有一定研究的,请移步: <JMir——Java版热血传奇2 ...
- paper 37 : WINCE的BIB文件解析
WINCE的BIB文件解析 BIB的全称为Binary Image Builder,在Wince编译过程中的最后MakeImage阶段会用到BIB文件,BIB文件的作用是指示构建系统如何构建二进制映像 ...
- 如何让你的Apache支持include文件解析和支持shtml的相关配置
源地址:http://www.itokit.com/2011/0430/65992.html Apache支持include文件解析shtml首先要应该修改Apache配置文件httpd.conf . ...
随机推荐
- 用scikit-learn进行LDA降维
在线性判别分析LDA原理总结中,我们对LDA降维的原理做了总结,这里我们就对scikit-learn中LDA的降维使用做一个总结. 1. 对scikit-learn中LDA类概述 在scikit-le ...
- FFmpeg学习6:视音频同步
在上一篇文章中,视频和音频是各自独立播放的,并不同步.本文主要描述了如何以音频的播放时长为基准,将视频同步到音频上以实现视音频的同步播放的.主要有以下几个方面的内容 视音频同步的简单介绍 DTS 和 ...
- .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类
.NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除 ...
- In-Memory:内存优化表 DMV
在内存优化表的DMV中,有两个对象ID(Object ID): xtp_object_id 是内部的内存优化表(Internal Memory-Optimized Table)的ID,在对象的整个生命 ...
- IE的F12开发人员工具不显示问题
按下F12之后,开发人员工具在桌面上看不到,但是任务栏里有显示.将鼠标放在任务栏的开发人员工具上,出现一片透明的区域,选中之后却出不来.将鼠标移动到开发人员工具的缩略图上,右键-最大化,工具就全屏出现 ...
- Android学习路线总结,绝对干货
title: Android学习路线总结,绝对干货 tags: Android学习路线,Android学习资料,怎么学习android grammar_cjkRuby: true --- 一.前言 不 ...
- Python(九) Python 操作 MySQL 之 pysql 与 SQLAchemy
本文针对 Python 操作 MySQL 主要使用的两种方式讲解: 原生模块 pymsql ORM框架 SQLAchemy 本章内容: pymsql 执行 sql 增\删\改\查 语句 pymsql ...
- 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.1
HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...
- 敏捷转型历程 - Sprint3 回顾会
我: Tech Leader 团队:团队成员分布在两个城市,我所在的城市包括我有4个成员,另外一个城市包括SM有7个成员.另外由于我们的BA离职了,我暂代IT 的PO 职位.PM和我在一个城市,但他不 ...
- Jenkins的一个bug-同时build一个项目两次导致失败
我们有一个job A, A只是配置了一些参数,它会去触发模板job B. 我一开始点击构建A, 马上发现参数配置不对,于是撤消了构建,但是我没有发现B已经被触发,我重新配置参数,然后再次构建A,这个时 ...