Esempio n. 1
0
            /// <summary>
            /// Creates a <see cref="DataTable"/> object
            /// with columns matching the field mappings
            /// for this object. This is just a schema
            /// export.
            /// </summary>
            /// <returns></returns>
            public DataTable ToDataTable()
            {
                string tableName = DataModelContext.EntityMappings.TableMapping.Table;

                if (!string.IsNullOrEmpty(DataModelContext.EntityMappings.TableMapping.Schema) &&
                    DataModelContext.EntityMappings.TableMapping.Schema != "dbo")
                {
                    string schema = DataModelContext.EntityMappings.TableMapping.Schema;
                    if (!schema.EndsWith("."))
                    {
                        schema += ".";
                    }
                    tableName = schema + tableName;
                }
                var dt = new DataTable(tableName);

                foreach (var field_kvp in DataModelContext.EntityMappings.FieldMappings)
                {
                    DataModelColumnAttribute field = field_kvp.Value;
                    DataColumn dc;
                    try
                    {
                        dc = new DataColumn(field.ColumnName, field.TargetMemberType);
                    }
                    catch (NotSupportedException)
                    {
                        dc = new DataColumn(field.ColumnName);
                    }
                    dt.Columns.Add(dc);
                }
                return(dt);
            }
Esempio n. 2
0
 /// <summary>
 /// Gets or sets the value identified by the specified
 /// <paramref name="key"/>, which corresponds to the
 /// mapped database column name.
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public object this[string key]
 {
     get
     {
         foreach (var field_kvp in Mapping.FieldMappings)
         {
             DataModelColumnAttribute field = field_kvp.Value;
             if (field.ColumnName == null)
             {
                 field.ColumnName = field_kvp.Key;
             }
             if (field.ColumnName.ToLower() == key.ToLower())
             {
                 return(DataModel[field_kvp.Key]);
             }
         }
         if (DataModel["field:" + key] != null)
         {
             return(DataModel["field:" + key]);
         }
         throw new ArgumentException("Field mapping not found");
     }
     set
     {
         foreach (var field_kvp in Mapping.FieldMappings)
         {
             DataModelColumnAttribute field = field_kvp.Value;
             if (field.ColumnName.ToLower() == key.ToLower())
             {
                 DataModel[field_kvp.Key] = value;
                 return;
             }
         }
         var attr = new DataModelColumnAttribute(key)
         {
             DbType = DbTypeConverter.ToDbType(value.GetType())
         };
         Mapping.FieldMappings.Add("field:" + key, attr);
         DataModel["field:" + key] = value;
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Prepares the
        /// data to propagate to or from the <see cref="Entity"/> before
        /// the Entity is retrieved or before data changes are made and/or saved.
        /// </summary>
        /// <param name="syncTo"></param>
        public override void SynchronizeFields(SyncTo syncTo)
        {
            if (Type.IsDataModel() &&
                Type == GetUnwrappedType(Type))
            {
                return;
            }
            switch (syncTo)
            {
            case SyncTo.FieldMappedData:
                foreach (var field_kvp in EntityMappings.FieldMappings)
                {
                    DataModelColumnAttribute field = field_kvp.Value;

                    // todo: optimize with cached Action<T>
                    // see: http://msmvps.com/blogs/jon_skeet/archive/2008/08/09/making-reflection-fly-and-exploring-delegates.aspx

                    if (field.TargetMember is FieldInfo)
                    {
                        object val  = ((FieldInfo)field.TargetMember).GetValue(Entity);
                        object dval = this[field.TargetMember.Name];
                        if (((dval == null) != (val == null)) ||
                            (dval != null && !dval.Equals(val)))
                        {
                            this[field.TargetMember.Name] = val;
                        }
                    }
                    else if (field.TargetMember is PropertyInfo)
                    {
                        object val = ((PropertyInfo)field.TargetMember).GetValue(Entity, new object[] {});
                        if (val != null && !DataModelMap.TypeIsFieldMappable(val.GetType()))
                        {
                            if (DataModelMap.MapItems.ContainsKey(val.GetType()) &&
                                DataModelMap.GetEntityMapping(val.GetType()).PrimaryKeyColumns.Length == 1)
                            {
                                var map = DataModelMap.GetEntityMapping(val.GetType());
                                if (val is DataModel)
                                {
                                    val =
                                        ((DataModel)val).ColumnMappedValue[
                                            ((DataModel)val).EntityMappings.PrimaryKeyColumns[0]];
                                }
                                else
                                {
                                    val = val.GetType().GetProperty(
                                        map.PrimaryKeyColumns[0]).GetValue(val, new object[] { });
                                }
                            }
                        }
                        object dval = InnerData.ContainsKey(field.TargetMember.Name)
                                ? this[field.TargetMember.Name]
                                : null;
                        if (((dval == null) != (val == null)) ||
                            (dval != null && !dval.Equals(val)))
                        {
                            if (this.ModelData.ContainsKey(field.TargetMember.Name))
                            {
                                this[field.TargetMember.Name] = val;
                            }
                            else
                            {
                                var mapping = EntityMappings[field.TargetMember.Name];
                                if (mapping != null)
                                {
                                    var name = mapping.TargetMember.Name;
                                    if (this.ModelData.ContainsKey(name))
                                    {
                                        this[name] = val;
                                    }
                                    else if (this.ModelData.ContainsKey("field:" + mapping.ColumnName))
                                    {
                                        this["field:" + mapping.ColumnName] = val;
                                    }
                                }
                            }
                        }
                    }
                }
                break;

            case SyncTo.ClrMembers:
                foreach (var field_kvp in EntityMappings.FieldMappings)
                {
                    DataModelColumnAttribute field = field_kvp.Value;

                    // todo: optimize with cached Action<T>
                    // see: http://msmvps.com/blogs/jon_skeet/archive/2008/08/09/making-reflection-fly-and-exploring-delegates.aspx

                    if (field.TargetMember is FieldInfo)
                    {
                        object clrval = ((FieldInfo)field.TargetMember).GetValue(Entity);
                        object dicval = this[field.TargetMember.Name];
                        if (((clrval == null) != (dicval == null)) ||
                            (dicval != null && !dicval.Equals(clrval)))
                        {
                            ((FieldInfo)field.TargetMember).SetValue(
                                Entity, this[field.TargetMember.Name]);
                        }
                    }
                    else if (field.TargetMember is PropertyInfo)
                    {
                        if (DataModelMap.TypeIsFieldMappable(field.TargetMemberType))
                        {
                            object propval = ((PropertyInfo)field.TargetMember).GetValue(Entity, new object[] {});
                            object dicval  = this[field.TargetMember.Name];
                            if (dicval == DBNull.Value)
                            {
                                dicval = null;
                            }
                            if (((dicval == null) != (propval == null)) ||
                                (dicval != null && !dicval.Equals(propval)))
                            {
                                ((PropertyInfo)field.TargetMember).SetValue(
                                    Entity, dicval, new object[] {});
                            }
                        }
                        else
                        {
                            // todo maybe: assign loaded entity?
                        }
                    }
                }
                break;
            }
        }
Esempio n. 4
0
        private void ExecuteFieldMapBehaviors()
        {
            // Auto-infer IsIdentity if no field is declared as primary key
            // and no field is declared as identity and one member is named
            // "ID" and that member is an int or a long.
            bool hasPkOrIdent = false;
            DataModelColumnAttribute idFieldMapping = null;
            string typename = null;

            foreach (var field_kvp in FieldMappings)
            {
                var field = field_kvp.Value;
                if (!field.IsForeignKey)
                {
                    if ((field.IsIdentity && field.IsIdentityDefined) ||
                        (field.IsPrimaryKey && field.IsPrimaryKeyDefined))
                    {
                        hasPkOrIdent = true;
                    }
                    if (typename == null)
                    {
                        typename = field.TargetMember.DeclaringType.Name.ToLower();
                    }
                    var propname = field.TargetMember.Name.ToLower();
                    if (propname == "id" || propname == typename + "id" || propname == typename + "_id")
                    {
                        idFieldMapping = field;
                    }
                }
            }
            if (!hasPkOrIdent && idFieldMapping != null &&
                (idFieldMapping.DbType == DbType.Int32 ||
                 idFieldMapping.DbType == DbType.Int64))
            {
                idFieldMapping.IsIdentity = true;
            }

            // Auto-infer a dictionary entry placeholder for foreign entity mappings
            // with no referenced foreign key column
            foreach (var fk in ForeignModelMappings)
            {
                //if (fk.Value.TargetMemberType.IsOrInherits(typeof(IEnumerable))) continue;
                var tmt   = GetEntityType(fk.Value.TargetMemberType);
                var ttmap = GetEntityMapping(tmt);
                var ff    = ttmap != null
                             ? ttmap.GetFieldMappingByDbColumnName(fk.Value.RelatedTableColumn)
                             : null;

                if (FieldMappings.ToList().Exists(p => p
                                                  .Value.ColumnName.ToLower() == fk.Value.LocalColumn.ToLower()))
                {
                    continue;
                }
                var fm = new DataModelColumnAttribute();
                if (ff != null)
                {
                    ff.CopyDeltaTo(fm);
                    fm.ColumnName       = fk.Value.LocalColumn;
                    fm.DbType           = fk.Value.LocalColumnDbType;
                    fm.SqlDbType        = fk.Value.LocalColumnSqlDbType;
                    fm.ColumnSize       = fk.Value.LocalColumnSize;
                    fm.IsNullable       = fk.Value.LocalColumnIsNullable;
                    fm.TargetMember     = fk.Value.TargetMember;
                    fm.TargetMemberType = fk.Value.TargetMemberType;
                    fm.IsPrimaryKey     = false;
                    fm.IsIdentity       = false;
                    FieldMappings.Add("field:" + fk.Value.LocalColumn, fm);
                }
                _FieldMapBehaviorsExecuted = true;
            }

            // predetermine NULLables based on CLR nullability
            foreach (var field_kvp in FieldMappings)
            {
                var field = field_kvp.Value;
                if (!field.IsNullableDefined)
                {
                    var  memtype  = field.TargetMemberType;
                    bool nullable = !memtype.IsValueType;
                    if (memtype.IsGenericType && memtype.GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        memtype  = memtype.GetGenericArguments()[0];
                        nullable = true;
                    }
                    field.IsNullable = (memtype.IsValueType || memtype == typeof(string)) && nullable && !field.IsPrimaryKey;
                }
            }
        }
Esempio n. 5
0
        private void LoadFieldMappingAttributes()
        {
            var hierarchy = new List <Type>();
            var t         = this.EntityType;

            while (t != typeof(DataModel) && t != typeof(object))
            {
                hierarchy.Insert(0, t);
                t = t.BaseType;
            }
            // walk up hierarchy
            foreach (var type in hierarchy)
            {
                var pis = type.GetProperties();
                var fis = type.GetFields();
                var mis = new Dictionary <MemberInfo, Type>();
                foreach (var fi in fis)
                {
                    mis.Add(fi, fi.FieldType);                     // fee fi fo fum
                }
                foreach (var pi in pis)
                {
                    mis.Add(pi, pi.PropertyType);
                }
                foreach (var mi_kvp in mis)
                {
                    var mi     = mi_kvp.Key;
                    var miType = mi_kvp.Value;
                    var attrs  = mi.GetCustomAttributes(typeof(DataModelColumnAttribute), false);
                    if (!TypeIsFieldMappable(miType))
                    {
                        if (attrs.Length > 0)
                        {
                            throw new InvalidAttributeException("Cannot apply a " + typeof(DataModelColumnAttribute).Name
                                                                + " to a member having a custom or complex type. "
                                                                + "Use " + typeof(ForeignDataModelAttribute).Name + ".",
                                                                mi.Name, (Attribute)attrs[0]);
                        }
                        continue;
                    }
                    foreach (DataModelColumnAttribute attr in attrs)
                    {
                        attr.TargetMember     = mi;
                        attr.TargetMemberType = miType;
                        if (string.IsNullOrEmpty(attr.ColumnName))
                        {
                            attr.ColumnName           = mi.Name;
                            attr.IsColumnNameInferred = true;
                        }
                        if (FieldMappings.ContainsKey(mi.Name) && !attr.ClearBaseObjectMapping)
                        {
                            attr.CopyDeltaTo(FieldMappings[mi.Name]);
                        }
                        else
                        {
                            FieldMappings[mi.Name] = attr;
                        }
                        var fm = FieldMappings[mi.Name];
                        if (fm.DataType == null)
                        {
                            var    def = miType;
                            Type[] genargs;
                            if (def.IsGenericType &&
                                (genargs = def.GetGenericArguments()).Length == 1)
                            {
                                def = genargs[0];
                            }
                            try
                            {
                                fm.DbType = DbTypeConverter.ToDbType(def);
                            }
                            catch { }
                        }
                    }
                }
            }
            if ((FieldMappings.Count == 0 && TableMapping.PropertyLoadBehavior
                 == InferProperties.OnlyAttributedOrAllIfNoneHaveAttributes) ||
                TableMapping.PropertyLoadBehavior == InferProperties.NotIgnored)
            {
                foreach (var type in hierarchy)
                {
                    var pis = type.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);
                    var fis = type.GetFields(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);
                    var mis = new Dictionary <MemberInfo, Type>();
                    foreach (var fi in fis)
                    {
                        mis.Add(fi, fi.FieldType);                     // fee fi fo fum
                    }
                    foreach (var pi in pis)
                    {
                        mis.Add(pi, pi.PropertyType);
                    }
                    foreach (var mi_kvp in mis)
                    {
                        var mi = mi_kvp.Key;
                        if (!FieldMappings.ContainsKey(mi.Name))
                        {
                            var miType       = mi_kvp.Value;
                            var ignoreAttrib = mi.GetCustomAttributes(typeof(DataModelIgnoreAttribute), false);
                            if (ignoreAttrib != null && ignoreAttrib.Length > 0)
                            {
                                continue;
                            }
                            var gt = miType;
                            if (!TypeIsFieldMappable(gt))
                            {
                                continue;
                            }
                            var attr = new DataModelColumnAttribute(mi.Name);
                            attr.TargetMember      = mi;
                            attr.TargetMemberType  = miType;
                            FieldMappings[mi.Name] = attr;
                            var fm = attr;
                            if (fm.DataType == null)
                            {
                                var    def = miType;
                                Type[] genargs;
                                if (def.IsGenericType &&
                                    (genargs = def.GetGenericArguments()).Length == 1)
                                {
                                    def = genargs[0];
                                }
                                try
                                {
                                    fm.DbType = DbTypeConverter.ToDbType(def);
                                }
                                catch
                                {
                                }
                            }
                        }
                    }
                }
            }
        }