private DataProperty CreateDataProperty(StructuralType structuralType, PropertyInfo pInfo)
        {
            var propType = pInfo.PropertyType;
            var dp       = new DataProperty(pInfo.Name);

            // TODO: handle isScalar
            if (typeof(IComplexObject).IsAssignableFrom(propType))
            {
                dp.ComplexType = MetadataStore.GetComplexType(propType);
                dp.IsNullable  = false;
                // complex Objects do not have defaultValues currently
            }
            else
            {
                var nnType = TypeFns.GetNonNullableType(propType);
                dp.ClrType = propType;

                dp.DataType     = DataType.FromClrType(nnType);
                dp.IsNullable   = TypeFns.IsNullableType(propType);
                dp.DefaultValue = dp.IsNullable ? null : dp.DataType.DefaultValue;
                var isEnumType = nnType.GetTypeInfo().IsEnum;
                if (isEnumType)
                {
                    dp.EnumTypeName = nnType.FullName;
                }
            }

            structuralType.AddDataProperty(dp);
            return(dp);
        }
예제 #2
0
 private Expression GetPropertyExpression(Expression expr, string propertyName, Type returnType)
 {
     if (TypeFns.IsNullableType(expr.Type))
     {
         var nullBaseExpression = Expression.Constant(null, expr.Type);
         var test = Expression.Equal(expr, nullBaseExpression);
         expr = Expression.Convert(expr, TypeFns.GetNonNullableType(expr.Type));
         Expression propExpr = Expression.PropertyOrField(expr, propertyName);
         propExpr = Expression.Convert(propExpr, TypeFns.GetNullableType(returnType));
         var nullExpr = Expression.Constant(null, TypeFns.GetNullableType(returnType));
         return(Expression.Condition(test, nullExpr, propExpr));
     }
     else
     {
         return(Expression.PropertyOrField(expr, propertyName));
     }
 }
        private void ParseObject(NodeContext nodeContext, EntityAspect targetAspect)
        {
            // backingStore will be null if not allowed to overwrite the entity.
            var backingStore   = (targetAspect == null) ? null : targetAspect.BackingStore;
            var dict           = (IDictionary <String, JToken>)nodeContext.Node;
            var structuralType = nodeContext.StructuralType;
            // needs to be the current namingConvention
            var nc = _mappingContext.EntityManager.MetadataStore.NamingConvention;

            dict.ForEach(kvp => {
                var key  = nc.ServerPropertyNameToClient(kvp.Key, structuralType);
                var prop = structuralType.GetProperty(key);
                if (prop != null)
                {
                    if (prop.IsDataProperty)
                    {
                        if (backingStore != null)
                        {
                            var dp = (DataProperty)prop;
                            if (dp.IsComplexProperty)
                            {
                                var newCo     = (IComplexObject)kvp.Value.ToObject(dp.ClrType);
                                var co        = (IComplexObject)backingStore[key];
                                var coBacking = co.ComplexAspect.BackingStore;
                                newCo.ComplexAspect.BackingStore.ForEach(kvp2 => {
                                    coBacking[kvp2.Key] = kvp2.Value;
                                });
                            }
                            else
                            {
                                var val = kvp.Value;
                                if (val.Type == JTokenType.Null && dp.ClrType != typeof(String) && !TypeFns.IsNullableType(dp.ClrType))
                                {
                                    // this can only happen if the client is nonnullable but the server is nullable.
                                    backingStore[key] = dp.DefaultValue;
                                }
                                else if (dp.IsEnumType || (dp.DataType.ClrType == typeof(TimeSpan)))
                                {
                                    backingStore[key] = val.ToObject(dp.ClrType, _customSerializer);
                                }
                                else
                                {
                                    backingStore[key] = val.ToObject(dp.ClrType);
                                }
                            }
                        }
                    }
                    else
                    {
                        // prop is a ComplexObject
                        var np = (NavigationProperty)prop;

                        if (kvp.Value.HasValues)
                        {
                            NodeContext newContext;
                            if (np.IsScalar)
                            {
                                var nestedOb = (JObject)kvp.Value;
                                newContext   = new NodeContext()
                                {
                                    Node = nestedOb, ObjectType = prop.ClrType, StructuralProperty = np
                                };
                                var entity = (IEntity)CreateAndPopulate(newContext);
                                if (backingStore != null)
                                {
                                    backingStore[key] = entity;
                                }
                            }
                            else
                            {
                                var nestedArray = (JArray)kvp.Value;
                                var navSet      = (INavigationSet)TypeFns.CreateGenericInstance(typeof(NavigationSet <>), prop.ClrType);

                                nestedArray.Cast <JObject>().ForEach(jo => {
                                    newContext = new NodeContext()
                                    {
                                        Node = jo, ObjectType = prop.ClrType, StructuralProperty = np
                                    };
                                    var entity = (IEntity)CreateAndPopulate(newContext);
                                    navSet.Add(entity);
                                });
                                // add to existing nav set if there is one otherwise just set it.
                                object tmp;
                                if (backingStore.TryGetValue(key, out tmp))
                                {
                                    var backingNavSet = (INavigationSet)tmp;
                                    navSet.Cast <IEntity>().ForEach(e => backingNavSet.Add(e));
                                }
                                else
                                {
                                    navSet.NavigationProperty = np;
                                    navSet.ParentEntity       = targetAspect.Entity;
                                    backingStore[key]         = navSet;
                                }
                            }
                        }
                        else
                        {
                            // do nothing
                            //if (!np.IsScalar) {
                            //  return TypeFns.ConstructGenericInstance(typeof(NavigationSet<>), prop.ClrType);
                            //} else {
                            //  return null;
                            //}
                        }
                    }
                }
                else
                {
                    if (backingStore != null)
                    {
                        backingStore[key] = kvp.Value.ToObject <Object>();
                    }
                }
            });
        }
예제 #4
0
        private Expression BuildBinaryExpr(Expression expr1, Expression expr2, Operator op)
        {
            if (expr1.Type != expr2.Type)
            {
                if (TypeFns.IsNullableType(expr1.Type) && !TypeFns.IsNullableType(expr2.Type))
                {
                    expr2 = Expression.Convert(expr2, expr1.Type);
                }
                else if (TypeFns.IsNullableType(expr2.Type) && !TypeFns.IsNullableType(expr1.Type))
                {
                    expr1 = Expression.Convert(expr1, expr2.Type);
                }

                if (HasNullValue(expr2) && CannotBeNull(expr1))
                {
                    expr1 = Expression.Convert(expr1, TypeFns.GetNullableType(expr1.Type));
                }
                else if (HasNullValue(expr1) && CannotBeNull(expr2))
                {
                    expr2 = Expression.Convert(expr2, TypeFns.GetNullableType(expr2.Type));
                }
            }

            if (op == BinaryOperator.Equals)
            {
                return(Expression.Equal(expr1, expr2));
            }
            else if (op == BinaryOperator.NotEquals)
            {
                return(Expression.NotEqual(expr1, expr2));
            }
            else if (op == BinaryOperator.GreaterThan)
            {
                return(Expression.GreaterThan(expr1, expr2));
            }
            else if (op == BinaryOperator.GreaterThanOrEqual)
            {
                return(Expression.GreaterThanOrEqual(expr1, expr2));
            }
            else if (op == BinaryOperator.LessThan)
            {
                return(Expression.LessThan(expr1, expr2));
            }
            else if (op == BinaryOperator.LessThanOrEqual)
            {
                return(Expression.LessThanOrEqual(expr1, expr2));
            }
            else if (op == BinaryOperator.StartsWith)
            {
                var mi = TypeFns.GetMethodByExample((String s) => s.StartsWith("abc"));
                return(Expression.Call(expr1, mi, expr2));
            }
            else if (op == BinaryOperator.EndsWith)
            {
                var mi = TypeFns.GetMethodByExample((String s) => s.EndsWith("abc"));
                return(Expression.Call(expr1, mi, expr2));
            }
            else if (op == BinaryOperator.Contains)
            {
                var mi = TypeFns.GetMethodByExample((String s) => s.Contains("abc"));
                return(Expression.Call(expr1, mi, expr2));
            }
            else if (op == BinaryOperator.In)
            {
                // TODO: need to generalize this past just 'string'
                var mi = TypeFns.GetMethodByExample((List <String> list) => list.Contains("abc"), expr1.Type);
                return(Expression.Call(expr2, mi, expr1));
            }

            return(null);
        }