Beispiel #1
0
        private MetaNavProperty CreateNavProperty(INavigation p)
        {
            var np = new MetaNavProperty();

            np.NameOnServer   = p.Name;
            np.EntityTypeName = NormalizeTypeName(p.GetTargetType().ClrType);
            np.IsScalar       = !p.IsCollection();
            // FK_<dependent type name>_<principal type name>_<foreign key property name>
            np.AssociationName = BuildAssocName(p);
            if (p.IsDependentToPrincipal())
            {
                np.AssociationName         = BuildAssocName(p);
                np.ForeignKeyNamesOnServer = p.ForeignKey.Properties.Select(fkp => fkp.Name).ToList();
            }
            else
            {
                var    invP = p.FindInverse();
                string assocName;
                if (invP == null)
                {
                    assocName = "Inv_" + BuildAssocName(p);
                }
                else
                {
                    assocName = BuildAssocName(invP);
                }
                np.AssociationName            = assocName;
                np.InvForeignKeyNamesOnServer = p.ForeignKey.Properties.Select(fkp => fkp.Name).ToList();
            }

            return(np);
        }
        private BreezeMetadata GetMetadataFromContext(DbContext dbContext)
        {
            var metadata = new BreezeMetadata();

            metadata.StructuralTypes = dbContext.Model.GetEntityTypes().Select(et => {
                var mt = new MetaType();
                metadata.StructuralTypes.Add(mt);
                mt.ShortName = et.Name;
                mt.Namespace = et.ClrType.Namespace;

                mt.DataProperties = et.GetProperties().Select(p => {
                    var dp = new MetaDataProperty();

                    dp.NameOnServer    = p.Name;
                    dp.IsNullable      = p.IsNullable;
                    dp.IsPartOfKey     = p.IsPrimaryKey();
                    dp.MaxLength       = p.GetMaxLength();
                    dp.DataType        = p.ClrType.ToString();
                    dp.ConcurrencyMode = p.IsConcurrencyToken ? "None" : "Identity";
                    var dfa            = p.GetAnnotations().Where(a => a.Name == "DefaultValue").FirstOrDefault();
                    if (dfa != null)
                    {
                        dp.DefaultValue = dfa.Value;
                    }
                    return(dp);
                }).ToList();
                mt.NavigationProperties = et.GetNavigations().Select(p => {
                    var np            = new MetaNavProperty();
                    np.NameOnServer   = p.Name;
                    np.EntityTypeName = p.GetTargetType().Name;
                    np.IsScalar       = !p.IsCollection();
                    // FK_<dependent type name>_<principal type name>_<foreign key property name>
                    np.AssociationName = BuildAssocName(p);
                    if (p.IsDependentToPrincipal())
                    {
                        np.AssociationName         = BuildAssocName(p);
                        np.ForeignKeyNamesOnServer = p.ForeignKey.Properties.Select(fkp => fkp.Name).ToList();
                    }
                    else
                    {
                        np.AssociationName            = BuildAssocName(p.FindInverse());
                        np.InvForeignKeyNamesOnServer = p.ForeignKey.Properties.Select(fkp => fkp.Name).ToList();
                    }

                    return(np);
                }).ToList();
                return(mt);
            }).ToList();
            return(metadata);
        }
Beispiel #3
0
        /// <summary>
        /// Make association property metadata for the entity.
        /// Also populates the ForeignKeyMap which is used for related-entity fixup in NHContext.FixupRelationships
        /// </summary>
        /// <param name="containingPersister">Entity Persister containing the property</param>
        /// <param name="propType">Association property</param>
        /// <param name="propName">Name of the property</param>
        /// <param name="dataProperties">Data properties already collected for the containingType.  "isPartOfKey" may be added to a property.</param>
        /// <param name="isKey">Whether the property is part of the key</param>
        /// <returns></returns>
        private MetaNavProperty MakeAssociationProperty(AbstractEntityPersister containingPersister, IAssociationType propType, string propName, List <MetaDataProperty> dataProperties, bool isKey)
        {
            var nmap = new MetaNavProperty();

            nmap.NameOnServer = propName;

            var relatedEntityType = GetEntityType(propType.ReturnedClass, propType.IsCollectionType);

            nmap.EntityTypeName = relatedEntityType.Name + ":#" + relatedEntityType.Namespace;
            nmap.IsScalar       = !propType.IsCollectionType;

            // the associationName must be the same at both ends of the association.
            Type containingType = containingPersister.EntityMetamodel.Type;
            var  columnNames    = GetPropertyColumnNames(containingPersister, propName, propType);

            nmap.AssociationName = GetAssociationName(containingType.Name, relatedEntityType.Name, columnNames);

            List <string> fkNames  = null;
            var           joinable = propType.GetAssociatedJoinable((ISessionFactoryImplementor)this._sessionFactory);

            if (propType.IsCollectionType)
            {
                // inverse foreign key
                var collectionPersister = joinable as AbstractCollectionPersister;
                if (collectionPersister != null)
                {
                    // many-to-many relationships do not have a direct connection on the client or in metadata
                    var elementPersister = collectionPersister.ElementPersister as AbstractEntityPersister;
                    if (elementPersister != null)
                    {
                        fkNames = GetPropertyNamesForColumns(elementPersister, columnNames);
                        if (fkNames != null)
                        {
                            nmap.InvForeignKeyNamesOnServer = fkNames;
                        }
                    }
                }
            }
            else
            {
                // Not a collection type - a many-to-one or one-to-one association
                var entityRelationship = containingType.FullName + '.' + propName;
                // Look up the related foreign key name using the column name
                fkNames = GetPropertyNamesForColumns(containingPersister, columnNames);
                if (fkNames != null)
                {
                    if (propType.ForeignKeyDirection == ForeignKeyDirection.ForeignKeyFromParent)
                    {
                        nmap.ForeignKeyNamesOnServer = fkNames;
                    }
                    else
                    {
                        nmap.InvForeignKeyNamesOnServer = fkNames;
                    }

                    // For many-to-one and one-to-one associations, save the relationship in ForeignKeyMap for re-establishing relationships during save
                    _map.ForeignKeyMap.Add(entityRelationship, string.Join(",", fkNames));
                    if (isKey)
                    {
                        foreach (var fkName in fkNames)
                        {
                            var relatedDataProperty = FindPropertyByName(dataProperties, fkName) as MetaDataProperty;
                            relatedDataProperty.IsPartOfKey = true;
                        }
                    }
                }
                else if (fkNames == null)
                {
                    nmap.ForeignKeyNamesOnServer = columnNames;
                    //nmap.Add("ERROR", "Could not find matching fk for property " + entityRelationship);
                    _map.ForeignKeyMap.Add(entityRelationship, string.Join(",", columnNames));
                    throw new ArgumentException("Could not find matching fk for property " + entityRelationship);
                }
            }

            return(nmap);
        }