private MtTypeDefinition BuildMtType(ISqlConnectionProvider connectionProvider, Type clrType, IMtTypeStorageProvider typeStorageProvider, bool forceComplexType) { if (_typeConverter.IsPrimitiveType(clrType)) { return(MtTypeDefinition.MakePrimitive(Guid.NewGuid(), clrType)); } // forceComplexType is the hack that prevents MT type system from traversing types of complex properties. // Instead we mark such properties as 'complex' at later will store them as JSON if (forceComplexType) { return(MtTypeDefinition.MakeComplexType(Guid.NewGuid(), clrType)); } var mtType = MtTypeDefinition.MakeType(Guid.NewGuid(), clrType); int propId = 0; foreach (var prop in clrType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) { // prevent type parsing for properties: set forceComplexType = true var propType = ResolveMtType(connectionProvider, prop.PropertyType, typeStorageProvider, true, true); mtType.Properties.Add(new MtPropertyInfo(propId++, prop.Name, mtType, propType)); } return(mtType); }
private void CacheTypeDependences(ISqlConnectionProvider connectionProvider, MtTypeDefinition typeDefinition, IMtTypeStorageProvider typeStorageProvider) { if (_clrTypeMappings.ContainsKey(typeDefinition.ClrType)) { return; } // this type was not saved to the DB yet. Request storage provider to persist this type in storage provider's unit of work scope. // this logic shall not create duplicates because storage provider checks if type was alredy persisted before saving. if (_isUnsavedType.Contains(typeDefinition.Id)) { typeStorageProvider.PersistType(connectionProvider, typeDefinition); } _clrTypeMappings[typeDefinition.ClrType] = typeDefinition; if (typeDefinition.Properties != null) { foreach (var mtPropertyInfo in typeDefinition.Properties) { CacheTypeDependences(connectionProvider, mtPropertyInfo.MtPropertyType, typeStorageProvider); } } }
public MtObject ConvertToMt(object instance, MtTypeDefinition mtTypeDefinition) { var mtObject = new MtObject(mtTypeDefinition); var properties = instance.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var propertyInfo in properties) { if (!propertyInfo.CanRead || propertyInfo.GetIndexParameters().Length > 0) { continue; } var mtProp = mtTypeDefinition.Properties.FirstOrDefault(x => x.Name == propertyInfo.Name); if (mtProp == null) { continue; } var value = propertyInfo.GetValue(instance); mtObject.Values[mtProp.Index] = ConvertToDbCanonicalFormat(value); } return(mtObject); }
public object ConvertFromDbCanonicalFormat(string value, MtTypeDefinition type) { if (value == null) { return(null); } var isNullable = type.ClrType.IsGenericType && type.ClrType.GetGenericTypeDefinition() == typeof(Nullable <>); object rawValue; if (type.IsComplexType) { return(JsonConvert.DeserializeObject(value, type.ClrType)); } if (type.ClrType == typeof(DateTime) || type.ClrType == typeof(DateTime?)) { rawValue = DateTime.Parse(value, null); } else { rawValue = Convert.ChangeType(value, type.ClrType, CultureInfo.InvariantCulture); } if (isNullable) { return(Activator.CreateInstance(type.ClrType, rawValue)); } return(rawValue); }
public MtObject(MtTypeDefinition mtTypeDefinition) { if (mtTypeDefinition.IsComplexType || mtTypeDefinition.IsPrimitive) { throw new ArgumentException("Can't create MtObject from primitive or complex type definition"); } MtTypeDefinition = mtTypeDefinition; Values = new string[mtTypeDefinition.Properties.Count]; }
public static AstNode Convert(Expression expression, MtTypeDefinition type) { if (expression == null) { return(null); } var visitor = new AstConverterExpressionVisitor(type); visitor.Visit(expression); return(visitor.GetRoot()); }
private AstNode BuildKeyPropertyExpression(Manifest curManifest, MtTypeDefinition type) { var pk = curManifest.GetPrimaryKey(); if (pk.Length == 0) { return(null); } AstNode root = null; var manifestType = curManifest.GetType(); foreach (var pkProp in pk) { var member = manifestType.GetProperty(pkProp); if (member == null) { throw new Exception(string.Format("Failed to find property '{0}' specified as part of primary key. Manifest {1}", pkProp, manifestType)); } var value = member.GetValue(curManifest); var mtProp = type.Properties.FirstOrDefault(x => x.Name == pkProp); if (mtProp == null) { throw new Exception(string.Format("Failed to find MT property '{0}' specified as part of primary key. Manifest {1}", pkProp, manifestType)); } var op = new BinaryOpNode(MtBinaryOp.Eq) { Left = new LoadFieldNode(mtProp.Index), Right = new LoadConstNode(value) }; if (root == null) { root = op; } else { root = new BinaryOpNode(MtBinaryOp.And) { Left = root, Right = op }; } } return(root); }
private AstNode ConvertToAst(Expression expression, MtTypeDefinition type) { return(ExpressionToAstConverter.Convert(expression, type)); }
public AstConverterExpressionVisitor(MtTypeDefinition type) { _type = type; }