예제 #1
0
        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);
        }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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];
        }
예제 #6
0
        public static AstNode Convert(Expression expression, MtTypeDefinition type)
        {
            if (expression == null)
            {
                return(null);
            }

            var visitor = new AstConverterExpressionVisitor(type);

            visitor.Visit(expression);

            return(visitor.GetRoot());
        }
예제 #7
0
        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);
        }
예제 #8
0
 private AstNode ConvertToAst(Expression expression, MtTypeDefinition type)
 {
     return(ExpressionToAstConverter.Convert(expression, type));
 }
예제 #9
0
 public AstConverterExpressionVisitor(MtTypeDefinition type)
 {
     _type = type;
 }