/// <summary> /// 从POCO实体类获取跟当前实体类的属性名称相同的属性的值,拷贝到当前实体类中,完成数据的映射。 /// 要求拷贝的同名属性是读写属性且类型相同。 /// </summary> /// <param name="pocoClass">POCO实体类,提供源数据</param> /// <param name="isChange">是否改变属性的修改状态</param> /// <returns>映射成功的属性数量</returns> public int MapFrom(object pocoClass, bool isChange) { if (pocoClass == null) { return(0); } int count = 0; int fcount = this.PropertyNames.Length; INamedMemberAccessor[] accessors = new INamedMemberAccessor[fcount]; DelegatedReflectionMemberAccessor drm = new DelegatedReflectionMemberAccessor(); Type type = pocoClass.GetType(); var ef = EntityFieldsCache.Item(this.GetType()); for (int i = 0; i < fcount; i++) { //实体类的属性字段可能跟属性名称不一样 edit at 2015.2.11 string perpertyName = ef.GetPropertyName(PropertyNames[i]); accessors[i] = drm.TryFindAccessor(type, perpertyName); } for (int i = 0; i < fcount; i++) { if (accessors[i] != null) { this.PropertyValues[i] = accessors[i].GetValue(pocoClass); if (isChange) //设置属性修改状态 { this.changedlist[i] = true; } count++; } } return(count); }
public List <T> QueryList <T>(IDataReader reader) where T : class, new() { List <T> list = new List <T>(); using (reader) { if (reader.Read()) { int fcount = reader.FieldCount; INamedMemberAccessor[] accessors = new INamedMemberAccessor[fcount]; DelegatedReflectionMemberAccessor drm = new DelegatedReflectionMemberAccessor(); for (int i = 0; i < fcount; i++) { accessors[i] = drm.FindAccessor <T>(reader.GetName(i)); } do { T t = new T(); for (int i = 0; i < fcount; i++) { if (!reader.IsDBNull(i)) { accessors[i].SetValue(t, reader.GetValue(i)); } } list.Add(t); } while (reader.Read()); } } return(list); }
/// <summary> /// 将当前实体类的属性值映射到相同属性名称的POCO实体类中。要求拷贝的同名属性是读写属性且类型相同。 /// </summary> /// <param name="pocoClass">POCO实体类</param> /// <returns>映射成功的属性数量</returns> public int MapToPOCO(object pocoClass) { if (pocoClass == null) { return(0); } int count = 0; int fcount = this.PropertyNames.Length; INamedMemberAccessor[] accessors = new INamedMemberAccessor[fcount]; DelegatedReflectionMemberAccessor drm = new DelegatedReflectionMemberAccessor(); Type type = pocoClass.GetType(); for (int i = 0; i < fcount; i++) { accessors[i] = drm.TryFindAccessor(type, PropertyNames[i]); } for (int i = 0; i < fcount; i++) { if (accessors[i] != null) { accessors[i].SetValue(pocoClass, this.PropertyValues[i]); count++; } } return(count); }
/// <summary> /// 采用快速的方法,将数据阅读器的结果映射到一个POCO类的列表上 /// </summary> /// <typeparam name="T">POCO类类型</typeparam> /// <param name="reader">抽象数据阅读器</param> /// <returns>POCO类的列表</returns> public static List <T> QueryList <T>(IDataReader reader) where T : class, new() { List <T> list = new List <T>(); using (reader) { if (reader.Read()) { int fcount = reader.FieldCount; //使用类型化委托读取正确的数据,解决MySQL等数据库可能的问题,感谢网友 @卖女孩的小肥羊 发现此问题 Dictionary <Type, MyFunc <IDataReader, int, object> > readerDelegates = DataReaderDelegate(); MyFunc <IDataReader, int, object>[] getDataMethods = new MyFunc <IDataReader, int, object> [fcount]; INamedMemberAccessor[] accessors = new INamedMemberAccessor[fcount]; DelegatedReflectionMemberAccessor accessorMethod = new DelegatedReflectionMemberAccessor(); for (int i = 0; i < fcount; i++) { accessors[i] = accessorMethod.FindAccessor <T>(reader.GetName(i)); //修改成从POCO实体类的属性上来获取DataReader类型化数据访问的方法,而不是之前的DataReader 的字段的类型 if (!readerDelegates.TryGetValue(accessors[i].MemberType, out getDataMethods[i])) { getDataMethods[i] = (rd, ii) => rd.GetValue(ii); } } do { T t = new T(); for (int i = 0; i < fcount; i++) { if (!reader.IsDBNull(i)) { MyFunc <IDataReader, int, object> read = getDataMethods[i]; object value = read(reader, i); accessors[i].SetValue(t, value); } } list.Add(t); } while (reader.Read()); } } return(list); }
/// <summary> /// 从datareader读取数据到实体对象,实体的属性名称必须与数据库中的字段名称一致 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="reader"></param> /// <returns></returns> public static IEnumerable <T> ReadTo <T>(this IDataReader reader) where T : new() { List <T> list = new List <T>(); if (reader.Read()) { int fcount = reader.FieldCount; INamedMemberAccessor <T>[] accessors = new INamedMemberAccessor <T> [fcount]; PropertyAccessorManager drm = new PropertyAccessorManager(); for (int i = 0; i < fcount; i++) { accessors[i] = drm.FindAccessor <T>(reader.GetName(i)); } do { T t = new T(); for (int i = 0; i < fcount; i++) { if (!reader.IsDBNull(i) && accessors[i] != null) { accessors[i].SetValue(t, reader.GetValue(i)); } } list.Add(t); //yield return t; } while (reader.Read()); } if (reader != null) { reader.Close(); } return(list); }
/// <summary> /// 将当前实体类的属性值(非空值)映射到相同属性名称的POCO实体类中。要求拷贝的同名属性是读写属性且类型相同。 /// </summary> /// <param name="pocoClass">POCO实体类</param> /// <returns>映射成功的属性数量</returns> public int MapToPOCO(object pocoClass) { if (pocoClass == null) { return(0); } int count = 0; int fcount = this.PropertyNames.Length; INamedMemberAccessor[] accessors = new INamedMemberAccessor[fcount]; DelegatedReflectionMemberAccessor drm = new DelegatedReflectionMemberAccessor(); Type type = pocoClass.GetType(); var ef = EntityFieldsCache.Item(this.GetType()); for (int i = 0; i < fcount; i++) { //实体类的属性字段可能跟属性名称不一样 edit at 2015.10.24 string perpertyName = ef.GetPropertyName(PropertyNames[i]); accessors[i] = drm.TryFindAccessor(type, perpertyName); } for (int i = 0; i < fcount; i++) { if (accessors[i] != null) { //this.PropertyValues[i] 可能为空,这会导致下面的赋值报错 //这种情况可能发生在实体类的数据是经过OQL部分Select 字段造成的,或者字段本身的值为NULL object Value = this.PropertyValues[i]; if (Value != null && Value != DBNull.Value) { accessors[i].SetValue(pocoClass, this.PropertyValues[i]); count++; } } } return(count); }