示例#1
0
        /// <summary>
        /// Obtain a <see cref="FieldMap"/> instance from the current map. The field
        /// must be a foreign key reference to the given property on the given type.
        /// </summary>
        /// <param name="referencedType">The type to which the property should refer</param>
        /// <param name="propertyName">The name of the property on the referenced type</param>
        /// <returns>The FieldMap of the foreign key property from this map</returns>
        public FieldMap GetForeignKeyFieldMap(Type referencedType, string propertyName)
        {
            ObjectMap referencedMap = ObjectFactory.GetMap(broker, referencedType);
            FieldMap  fm            = GetForeignKeyFieldMap(referencedMap.QuotedTableName,
                                                            referencedMap.GetFieldMap(propertyName).QuotedColumnName);

            // If no relation was found, try the reverse
            // TODO this is only here because relation info is only stored with the map
            // having the foreign key column; it will be removed in the future
            if (fm == null)
            {
                foreach (FieldMap reverse in Fields)
                {
                    fm = referencedMap.GetForeignKeyFieldMap(QuotedTableName, reverse.QuotedColumnName);
                    if (fm != null && fm.MemberName == propertyName)
                    {
                        return(reverse);
                    }
                    else
                    {
                        fm = null;
                    }
                }
            }
            Check.VerifyNotNull(fm, Error.DeveloperError,
                                "The type {0} does not have a foreign key relation to the property {1} " +
                                "of type {2}. Check if you need to add a ForeignKey attribute.",
                                Type.Name, propertyName, referencedType);
            return(fm);
        }
示例#2
0
        /// <summary>
        /// Obtain a key for the specified object instance and property names. The returned
        /// key will contain the corresponding column names for the type, and thus foreign
        /// key columns must use identical naming for this to work.
        /// </summary>
        /// <param name="broker">The optional PersistenceBroker instance to use for obtaining the
        /// ObjectMap for the supplied object instance. If this parameter is null, Gentle will try
        /// to infer the broker from the object instance. If that fails, it will use the default
        /// provider.</param>
        /// <param name="key">An optional existing key to add the values to</param>
        /// <param name="isPropertyKeys">False is key indexers are column names, true for property names</param>
        /// <param name="instance">The object instance whose property values will be used</param>
        /// <param name="members">The names of the properties to include in the key</param>
        /// <returns>The key</returns>
        public static Key GetKey(PersistenceBroker broker, Key key, bool isPropertyKeys, object instance, params string[] members)
        {
            Check.VerifyNotNull(instance, Error.NullParameter, "instance");
            // try to infer broker from instance
            if (broker == null && instance is IBrokerLock)
            {
                broker = (instance as IBrokerLock).SessionBroker;
            }
            // WARNING/TODO if broker is null here and no ObjectMap yet exists for the type,
            // the DefaultProvider will be used to create the ObjectMap
            ObjectMap map = ObjectFactory.GetMap(broker, instance);

            // only set source type reference if this is a new key
            if (key == null)
            {
                key = new Key(map.GetTableName(instance), instance.GetType(), isPropertyKeys);
            }
            //else
            //	Check.Verify( ! key.isPropertyKeys, Error.DeveloperError,
            //		"Unable to combine keys containing property names due to possible name clashes." );
            Check.VerifyEquals(key.isPropertyKeys, isPropertyKeys, "Cannot combine property and " +
                               "column names in a single key - use one or the other.");
            Check.VerifyNotNull(members, Error.NullParameter, "members");
            // process the list of specified properties
            foreach (string memberName in members)
            {
                FieldMap fm = isPropertyKeys ? map.GetFieldMap(memberName) : map.GetFieldMapFromColumn(memberName);
                Check.VerifyNotNull(fm, Error.NoProperty, map.Type, memberName);                   // FIXME outdated error message
                object memberValue = fm.GetValue(instance);
                // translate foreign references to local names
                if (key.SourceType != map.Type)
                {
                    // WARNING/TODO if broker is null here and no ObjectMap yet exists for the type,
                    // the DefaultProvider will be used to create the ObjectMap
                    ObjectMap keyMap = ObjectFactory.GetMap(broker, key.SourceType);
                    fm = keyMap.GetForeignKeyFieldMap(map.TableName, fm.ColumnName);
                }
                key[isPropertyKeys ? fm.MemberName : fm.ColumnName] = memberValue;
            }
            // add concurrency value if enabled and instance has revision column
            if (GentleSettings.ConcurrencyControl && map.ConcurrencyMap != null)
            {
                long version = Convert.ToInt64(map.ConcurrencyMap.GetValue(instance));
                key[isPropertyKeys ? map.ConcurrencyMap.MemberName : map.ConcurrencyMap.ColumnName] = version;
            }
            return(key);
        }
示例#3
0
 internal Key ResolveForeignKeyReferences(Type type, Key key)
 {
     // determine whether we need to translate names
     if (key.SourceType != null && key.SourceType != type)
     {
         // translate column names in key to foreign key name in table used by type
         Key       fkKey = new Key(type, false);
         ObjectMap map   = ObjectFactory.GetMap(this, key.SourceType);
         ObjectMap fkMap = ObjectFactory.GetMap(this, type);
         foreach (string name in key.Keys)
         {
             string   fieldName = key.isPropertyKeys ? name : map.GetPropertyName(name);
             FieldMap fkfm      = fkMap.GetForeignKeyFieldMap(map.Type, fieldName);
             fkKey[fkfm.ColumnName] = key[name];
         }
         key = fkKey;
     }
     return(key);
 }