public ObjectDataRecord(object poco, DbConfig config, int depth) { _poco = poco; _config = config; Depth = depth; _classTypeCache = config.GetOrCreateClassInfoCache(poco.GetType()); RecordsAffected = -1; FieldCount = _classTypeCache.Propertys.Count; }
internal QueryLazyEnumerator(IQueryContainer queryContainer, Type type) { _type = queryContainer.AccessLayer.GetClassInfo(type); _accessLayer = new DbAccessLayer(queryContainer.AccessLayer.Database); _accessLayer.Database.Connect(IsolationLevel.ReadCommitted); var command = queryContainer.Compile(); queryContainer.AccessLayer.RaiseSelect(command); _executeReader = command.ExecuteReader(); }
internal XmlDataRecord(string xmlStream, DbClassInfoCache target) { _target = target; if (string.IsNullOrEmpty(xmlStream)) { baseElement = new XElement("faild"); return; } baseElement = XDocument.Parse(xmlStream).Elements().ElementAt(0); }
/// <summary> /// Generates a Function with a Full ado.net constructor beavior. /// It Creates a new Instance of <param name="target"></param> and then fills all public properties /// </summary> /// <param name="target"></param> /// <param name="settings"></param> /// <param name="importNameSpace"></param> /// <returns></returns> public static CodeMemberMethod GenerateFactory(DbClassInfoCache target, FactoryHelperSettings settings, CodeNamespace importNameSpace) { var codeFactory = GenerateTypeConstructor(true); var super = new CodeVariableReferenceExpression("super"); var pocoVariable = new CodeVariableDeclarationStatement(target.Type, "super"); codeFactory.Statements.Add(pocoVariable); var codeAssignment = new CodeAssignStatement(super, new CodeObjectCreateExpression(target.Type)); codeFactory.Statements.Add(codeAssignment); GenerateBody(target, settings, importNameSpace, codeFactory, super); codeFactory.ReturnType = new CodeTypeReference(target.Type); codeFactory.Statements.Add(new CodeMethodReturnStatement(super)); return codeFactory; }
public void Dispose() { this._classTypeCache = null; }
/// <summary> /// Creates a new Instance based on possible Ctor's and the given /// <paramref name="reader" /> /// </summary> /// <returns></returns> public object SetPropertysViaReflection(DbClassInfoCache type, IDataRecord reader, DbAccessType? accessType) { return type.SetPropertysViaReflection(reader, DbAccessType, Config); }
internal XmlDataRecord(XDocument baseElement, DbClassInfoCache target) { _target = target; this.baseElement = baseElement.Elements().ElementAt(0); }
/// <summary> /// Maps propertys to database of given type /// </summary> /// <returns></returns> internal static IEnumerable <string> CreatePropertyNames(DbClassInfoCache type, bool ignorePk = false) { return(ignorePk ? FilterDbSchemaMapping(type, type.PrimaryKeyProperty.DbName) : FilterDbSchemaMapping(type)); }
/// <summary> /// Anonymous type check by naming convention /// </summary> /// <returns></returns> internal static bool IsAnonymousType(this DbClassInfoCache type) { //http://stackoverflow.com/questions/1650681/determining-whether-a-type-is-an-anonymous-type return(type.Type.Namespace == null); }
///// <summary> ///// Creates a Strong typed query that awaits a Result ///// </summary> ///// <returns></returns> //public RootQuery Query(Type targetType) //{ // return new RootQuery(this, targetType); //} ///// <summary> ///// Creates a Strong typed query that awaits a Result ///// </summary> ///// <returns></returns> //public RootQuery Query<T>() //{ // return new RootQuery(this, typeof(T)); //} /// <summary> /// Creates a new Instance based on possible Ctor's and the given /// <paramref name="reader" /> /// </summary> /// <returns></returns> public object SetPropertysViaReflection(DbClassInfoCache type, IDataRecord reader) { return SetPropertysViaReflection(type, reader, DbAccessType); }
/// <summary> /// Generates a Constructor with a Full Ado.Net constructor /// </summary> /// <param name="target"></param> /// <param name="settings"></param> /// <param name="importNameSpace"></param> /// <returns></returns> public static CodeMemberMethod GenerateConstructor(DbClassInfoCache target, FactoryHelperSettings settings, CodeNamespace importNameSpace) { var codeConstructor = GenerateTypeConstructor(); GenerateBody(target, settings, importNameSpace, codeConstructor, new CodeBaseReferenceExpression()); return codeConstructor; }
/// <summary> /// Maps all propertys of /// <paramref name="type" /> /// into the Database columns /// </summary> /// <returns></returns> internal static IEnumerable <string> FilterDbSchemaMapping(this DbClassInfoCache type, params string[] ignore) { return(type.LocalToDbSchemaMapping().Where(f => !ignore.Contains(f))); }
public static void GenerateBody(DbClassInfoCache sourceType, FactoryHelperSettings settings, CodeNamespace importNameSpace, CodeMemberMethod container, CodeExpression target) { GenerateBody(sourceType.Propertys, settings, importNameSpace, container, target); }
internal IEnumerable EnumerateDataRecords(IDbCommand query, bool direct, DbClassInfoCache type) { if (direct) { return EnumerateDataRecords(query) .Select(f => SetPropertysViaReflection(type, f)) .ToArray(); } else { return EnumerateDirectDataRecords(query, type); } }
public static object ReflectionPropertySet( DbConfig config, object instance, DbClassInfoCache info, IDataRecord reader, Dictionary<int, DbPropertyInfoCache> cache, DbAccessType? dbAccessType) { if (instance == null) throw new ArgumentNullException("instance"); if (info == null) throw new ArgumentNullException("info"); if (reader == null) return instance; //Left c# property name and right the object to read from the reader //var listofpropertys = new Dictionary<string, object>(); var propertys = info.Propertys.ToArray(); var instanceOfFallbackList = new Dictionary<string, object>(); if (cache == null) { cache = new Dictionary<int, DbPropertyInfoCache>(); for (var i = 0; i < reader.FieldCount; i++) { DbPropertyInfoCache val = null; info.Propertys.TryGetValue(info.SchemaMappingDatabaseToLocal(reader.GetName(i)), out val); cache.Add(i, val); } } for (var i = 0; i < reader.FieldCount; i++) { var property = cache[i]; var value = reader.GetValue(i); if (property != null) { var attributes = property.Attributes; var valueConverterAttributeModel = attributes.FirstOrDefault(s => s.Attribute is ValueConverterAttribute); //Should the SQL value be converted if (valueConverterAttributeModel != null) { var converter = valueConverterAttributeModel.Attribute as ValueConverterAttribute; //Create the converter and then convert the value before everything else var valueConverter = converter.CreateConverter(); value = valueConverter.Convert(value, property.PropertyInfo.PropertyType, converter.Parameter, CultureInfo.CurrentCulture); } var xmlAttributeModel = attributes.FirstOrDefault(s => s.Attribute is FromXmlAttribute); //should the Content be considerd as XML text? if (xmlAttributeModel != null) { //Get the XML text and check if its null or empty var xmlStream = value.ToString(); if (string.IsNullOrEmpty(xmlStream)) { continue; } //Check for List //if this is a list we are expecting other entrys inside if (property.CheckForListInterface()) { //target Property is of type list //so expect a xml valid list Take the first element and expect the propertys inside this first element var record = XmlDataRecord.TryParse(xmlStream, property.PropertyInfo.PropertyType.GetGenericArguments().FirstOrDefault(), false, config); var xmlDataRecords = record.CreateListOfItems(); var genericArguments = config.GetOrCreateClassInfoCache(property.PropertyInfo.PropertyType.GetGenericArguments().FirstOrDefault()); var enumerableOfItems = xmlDataRecords.Select( s => DbAccessLayerHelper.SetPropertysViaReflection(genericArguments, s, dbAccessType, config)).ToList(); object castedList; if (genericArguments.Type.IsClass && genericArguments.Type.GetInterface("INotifyPropertyChanged") != null) { var caster = typeof(DbCollection<>).MakeGenericType(genericArguments.Type).GetConstructor(new[] {typeof(IEnumerable)}); Debug.Assert(caster != null, "caster != null"); castedList = caster.Invoke(new object[] {enumerableOfItems}); } else { var caster = typeof(NonObservableDbCollection<>).MakeGenericType(genericArguments.Type) .GetConstructor(new[] {typeof(IEnumerable)}); Debug.Assert(caster != null, "caster != null"); castedList = caster.Invoke(new object[] {enumerableOfItems}); } property.Setter.Invoke(instance, castedList); } else { var classInfo = config.GetOrCreateClassInfoCache(property .PropertyInfo .PropertyType); var xmlDataRecord = XmlDataRecord.TryParse(xmlStream, property.PropertyInfo.PropertyType, true, config); //the t var xmlSerilizedProperty = DbAccessLayerHelper.SetPropertysViaReflection(classInfo, xmlDataRecord, dbAccessType, config); property.Setter.Invoke(instance, xmlSerilizedProperty); } } else if (value is DBNull || value == null) { property.Setter.Invoke(instance, new object[] {null}); } else { object changedType; if (value.GetType() != property.PropertyInfo.PropertyType) { changedType = DataConverterExtensions.ChangeType(value, property.PropertyInfo.PropertyType); } else { changedType = value; } property.Setter.Invoke(instance, changedType); } } //This variable is null if we tried to find a property with the LoadNotImplimentedDynamicAttribute but did not found it else if (instanceOfFallbackList != null) { //no property found Look for LoadNotImplimentedDynamicAttribute property to include it if (instanceOfFallbackList.Any()) { instanceOfFallbackList.Add(reader.GetName(i), value); } else { var maybeFallbackProperty = propertys.FirstOrDefault( s => s.Value.Attributes.Any(e => e.Attribute is LoadNotImplimentedDynamicAttribute)); if (maybeFallbackProperty.Value != null) { instanceOfFallbackList = (Dictionary<string, object>) maybeFallbackProperty.Value.Getter.Invoke(instance); if (instanceOfFallbackList == null) { instanceOfFallbackList = new Dictionary<string, object>(); maybeFallbackProperty.Value.Setter.Invoke(instance, instanceOfFallbackList); } instanceOfFallbackList.Add(reader.GetName(i), value); } else { instanceOfFallbackList = null; } } } } //foreach (var item in listofpropertys) //{ // var property = propertys.FirstOrDefault(s => s.PropertyName == item.Key); //} if (reader is EgarDataRecord) { (reader as IDisposable).Dispose(); } return instance; }
/// <summary> /// Creates an instance based on a Ctor injection or Reflection loading /// or when using a MsCoreLib type direct enumeration /// </summary> /// <returns></returns> public static object CreateInstance(DbClassInfoCache classInfo, IDataRecord reader, out bool fullLoaded, DbAccessType? accessType = null) { if (classInfo.Type.Assembly == MsCoreLibAssembly && reader.FieldCount == 1) { fullLoaded = true; return reader.GetValue(0); } if (classInfo.Factory != null) { fullLoaded = classInfo.FullFactory; return classInfo.Factory(reader); } var objectFactorys = classInfo.Constructors.Where(s => s.Arguments.Count == 1 && s.Arguments.First().Type == typeof(IDataRecord)) .ToArray(); var constructor = objectFactorys.FirstOrDefault(s => s.Attributes.Any(f => f.Attribute is ObjectFactoryMethodAttribute && (!accessType.HasValue || ((ObjectFactoryMethodAttribute) f.Attribute).TargetDatabase == accessType.Value))); if (constructor == null) constructor = objectFactorys.FirstOrDefault(); //maybe single ctor with param if (constructor != null) { if (constructor.Arguments.Count == 1 && constructor.Arguments.First().Type == typeof(IDataRecord)) { classInfo.FullFactory = true; classInfo.Factory = s => constructor.Invoke(new object[] {s}); return CreateInstance(classInfo, reader, out fullLoaded, accessType); } } else { //check for a Factory mehtod var factory = classInfo.Mehtods .FirstOrDefault(s => s.Attributes.Any(f => f.Attribute is ObjectFactoryMethodAttribute)); if (factory != null) { if (factory.MethodInfo.IsStatic) { var methodInfo = factory.MethodInfo as MethodInfo; if (methodInfo != null) { var returnType = methodInfo.ReturnParameter; if (returnType != null && returnType.ParameterType == classInfo.Type) { if (factory.Arguments.Count == 1 && factory.Arguments.First().Type == typeof(IDataRecord)) { classInfo.FullFactory = true; classInfo.Factory = s => factory.Invoke(new object[] {reader}); return CreateInstance(classInfo, reader, out fullLoaded, accessType); } } } } } } var emptyCtor = classInfo.Constructors.FirstOrDefault(f => !f.Arguments.Any()); if (emptyCtor == null) { throw new NotSupportedException( "You have to define ether an ObjectFactoryMethod as static or constructor with and IDataReader or an constructor without any arguments"); } classInfo.FullFactory = false; classInfo.Factory = s => emptyCtor.Invoke(new object[0]); return CreateInstance(classInfo, reader, out fullLoaded, accessType); }
/// <summary> /// Creates a new Instance based on possible Ctor's and the given /// <paramref name="reader" /> /// </summary> /// <returns></returns> public object SetPropertysViaReflection(DbClassInfoCache type, IDataRecord reader, Dictionary<int, DbPropertyInfoCache> mapping) { bool created; var source = CreateInstance(type, reader, out created); if (created) return source; #pragma warning disable 618 return ReflectionPropertySet(Config, source, type, reader, mapping, DbAccessType); #pragma warning restore 618 }
internal static Func<IDataRecord, object> CreateFactory(DbClassInfoCache target, FactoryHelperSettings settings) { var classCtorAttr = target.Attributes.First(s => s.Attribute is AutoGenerateCtorAttribute).Attribute as AutoGenerateCtorAttribute; CodeNamespace importNameSpace; importNameSpace = new CodeNamespace(target.Type.Namespace); var cp = new CompilerParameters(); string superName; var compiler = new CodeTypeDeclaration(); compiler.IsClass = true; var generateFactory = target.Type.IsSealed || classCtorAttr.CtorGeneratorMode == CtorGeneratorMode.FactoryMethod; CodeMemberMethod codeConstructor; var codeName = target.Name.Split('.').Last(); if (generateFactory) { codeConstructor = GenerateFactory(target, settings, importNameSpace); superName = codeName + "_Factory"; compiler.Attributes = MemberAttributes.Static; } else { compiler.BaseTypes.Add(target.Type); codeConstructor = GenerateConstructor(target, settings, importNameSpace); compiler.IsPartial = true; superName = codeName + "_Super"; } if (target.Constructors.Any(f => f.Arguments.Any())) { throw new TypeAccessException(string.Format("Target type '{0}' does not define an public parametherless constructor. POCO's!!!!", target.Name)); } compiler.Attributes |= MemberAttributes.Public; compiler.Name = superName; compiler.Members.Add(codeConstructor); cp.GenerateInMemory = true; if (settings.FileCollisonDetection == CollisonDetectionMode.Pessimistic) { cp.OutputAssembly = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\" + Guid.NewGuid().ToString("N") + "_Poco.dll"; } else { cp.OutputAssembly = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\" + target.Type.FullName + "_Poco.dll"; } settings.TempFileData.Add(cp.OutputAssembly); Assembly compiledAssembly; ConstructorInfo[] constructorInfos = null; TypeInfo targetType = null; if (File.Exists(cp.OutputAssembly) && settings.FileCollisonDetection == CollisonDetectionMode.Optimistic) { var bufferAssam = Assembly.Load(cp.OutputAssembly); targetType = target.Type.GetTypeInfo(); var type = bufferAssam.DefinedTypes.FirstOrDefault(s => s == targetType); if (targetType != null) constructorInfos = targetType.GetConstructors(); if(constructorInfos == null) throw new Exception(string.Format("A dll with a matching name for type: {0} was found and the FileCollisonDetection is Optimistic but no matching Constuctors where found", type.Name)); } if (constructorInfos == null) { var callingAssm = Assembly.GetEntryAssembly(); if (callingAssm == null) { //testing we are? callingAssm = Assembly.GetExecutingAssembly(); } if (settings.CreateDebugCode) { cp.TempFiles = new TempFileCollection(Path.GetDirectoryName(callingAssm.Location), true); cp.GenerateInMemory = false; cp.TempFiles.KeepFiles = true; cp.IncludeDebugInformation = true; } //cp.GenerateExecutable = true; cp.ReferencedAssemblies.Add(target.Type.Assembly.Location); cp.ReferencedAssemblies.Add("System.dll"); cp.ReferencedAssemblies.Add("System.Core.dll"); cp.ReferencedAssemblies.Add("System.Data.dll"); cp.ReferencedAssemblies.Add("System.Xml.dll"); cp.ReferencedAssemblies.Add("System.Xml.Linq.dll"); cp.ReferencedAssemblies.Add(typeof(DbAccessLayer).Assembly.Location); var compileUnit = new CodeCompileUnit(); foreach (var defaultNamespace in settings.DefaultNamespaces) { importNameSpace.Imports.Add(new CodeNamespaceImport(defaultNamespace)); } foreach (var additionalNamespace in target.Attributes.Where(f => f.Attribute is AutoGenerateCtorNamespaceAttribute).Select(f => f.Attribute as AutoGenerateCtorNamespaceAttribute)) { importNameSpace.Imports.Add(new CodeNamespaceImport(additionalNamespace.UsedNamespace)); } if (classCtorAttr.FullSateliteImport) { foreach (var referencedAssembly in target.Type.Assembly.GetReferencedAssemblies()) { cp.ReferencedAssemblies.Add(referencedAssembly.Name); } } importNameSpace.Types.Add(compiler); compileUnit.Namespaces.Add(importNameSpace); var provider = new CSharpCodeProvider(); var compileAssemblyFromDom = provider.CompileAssemblyFromDom(cp, compileUnit); if (compileAssemblyFromDom.Errors.Count > 0 && !settings.EnforceCreation) { var sb = new StringBuilder(string.Format("There are {0} errors due compilation.", compileAssemblyFromDom.Errors.Count)); int errNr = 0; foreach (CompilerError error in compileAssemblyFromDom.Errors) { sb.AppendLine(errNr++ + error.ErrorNumber + ":" + error.Column + "," + error.Line + " -> " + error.ErrorText); } var ex = new InvalidDataException(sb.ToString()); ex.Data.Add("Object", compileAssemblyFromDom); throw ex; } compiledAssembly = compileAssemblyFromDom.CompiledAssembly; targetType = compiledAssembly.DefinedTypes.First(); constructorInfos = targetType.GetConstructors(); if (!constructorInfos.Any()) { if (settings.EnforceCreation) return null; var ex = new InvalidDataException(string.Format("There are was an unknown error due compilation. No CTOR was build")); ex.Data.Add("Object", compileAssemblyFromDom); foreach (CompilerError error in compileAssemblyFromDom.Errors) { ex.Data.Add(error.ErrorNumber, error); } throw ex; } } var matchingCtor = constructorInfos.FirstOrDefault(s => { var param = s.GetParameters(); if (generateFactory) { if (param.Length < 1) return false; if (param.First().ParameterType != typeof(IDataRecord)) return false; } return true; }); var dm = new DynamicMethod("Create" + target.Name.Split('.')[0], target.Type, new[] { typeof(IDataRecord) }, target.Type, true); var il = dm.GetILGenerator(); if (generateFactory) { il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, targetType.GetMethod("Factory")); il.Emit(OpCodes.Ret); } else { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Newobj, matchingCtor); il.Emit(OpCodes.Ret); } if (!settings.CreateDebugCode) foreach (string tempFile in cp.TempFiles) { if (!tempFile.EndsWith("dll") && !tempFile.EndsWith("pdb")) File.Delete(tempFile); } var func = (Func<IDataRecord, object>)dm.CreateDelegate(typeof(Func<IDataRecord, object>)); return func; }
internal IEnumerable EnumerateDirectDataRecords(IDbCommand query, DbClassInfoCache info) { return Database.Run( s => { //Skip enumeration and parsing and make a Direct loading //This increeses Performance var records = new ArrayList(); using (var dr = query.ExecuteReader()) { try { do { while (dr.Read()) { records.Add(SetPropertysViaReflection(info, dr)); } } while (dr.NextResult()); } finally { dr.Close(); } } return records; }); }
public AnonymousClass(DbClassInfoCache classInfo, WeakReference reference) { ClassInfo = classInfo; Reference = reference; Objects = new HashSet <AnonymousObject>(); }
/// <summary> /// Returns all Propertys that can be loaded due reflection /// </summary> /// <returns></returns> public static string CreatePropertyCsv(this DbClassInfoCache type, bool ignorePk = false) { return(CreatePropertyNames(type, ignorePk).Aggregate((e, f) => e + ", " + f)); }