Beispiel #1
0
        private static IEnumerable <NavigationProperty> GenerateNavigationProperties(
            DataTable columnsTable,
            DataTable foreignKeyColumnsTable,
            DataTable foreignKeysTable,
            DataTable tablesTable,
            Table table,
            IReadOnlyCollection <Table> tables)
        {
            var props = new List <NavigationProperty>();
            // get foreign keys
            var foreignKeys = DbUtil.GetForeignKeysByTableId(
                columnsTable,
                foreignKeysTable,
                foreignKeyColumnsTable,
                tablesTable,
                table.ObjectId,
                table.TableName);

            // for each foreign key,
            foreignKeys.ForEach(a =>
            {
                var isDestinationForeignKeyAllNonNullable =
                    IsDestinationNullable(a, columnsTable);
                var isSourceForeignKeyAlsoPrimaryKey =
                    IsSourcePrimaryKey(table, a);
                var type = EntityDesignUtil.Singularize(
                    NamingUtil.GetTableName(a.DestinationTableName));
                var srcCol = a.Columns[0].SourceColumn;
                var prop   = new NavigationProperty
                {
                    DestinationMultiplicity =
                        // Zero: if any source foreign key columns are nullable
                        !isDestinationForeignKeyAllNonNullable
                        ? Multiplicity.Zero
                        // One: not Zero
                        : Multiplicity.One,
                    ForeignKey = a,
                    // *-1, 1-0/1
                    Name = SourceNavPropNames.TryGetValue(
                        a.SourceTableName + "." + string.Join("|", a.Columns.Select(b => b.SourceColumn)),
                        out var sourcePropName)
                        ? sourcePropName
                        : srcCol.ToLower().EndsWith("id") && srcCol.Length > 2
                        ? srcCol.Substring(0, srcCol.Length - 2)
                        : type,
                    SourceMultiplicity = isSourceForeignKeyAlsoPrimaryKey
                        ? Multiplicity.One
                        : Multiplicity.Many,
                    Type = type
                };
                // only add if not in NavigationPropertiesToSkip
                if (!NavPropsToSkip.ContainsKey(table.GeneratedName + "." + prop.Name))
                {
                    props.Add(prop);
                }
                // get destination table
                if (tables == null)
                {
                    return;
                }
                {
                    var destTable = tables
                                    .FirstOrDefault(b => b.TableName == a.DestinationTableName);
                    type = EntityDesignUtil.Singularize(
                        NamingUtil.GetTableName(a.SourceTableName));
                    var destProp = new NavigationProperty
                    {
                        DestinationMultiplicity = prop.SourceMultiplicity,
                        ForeignKey      = a,
                        InverseProperty = prop.Name,
                        Name            = DestNavPropNames.TryGetValue(
                            a.SourceTableName + "." + a.Columns[0].SourceColumn,
                            out var destPropName)
                            ? destPropName
                            : prop.SourceMultiplicity == Multiplicity.Many
                                ? EntityDesignUtil.Pluralize(type)
                                : type,
                        SourceMultiplicity = prop.DestinationMultiplicity,
                        Type = prop.SourceMultiplicity == Multiplicity.Many
                            ? "ICollection<" + type + ">"
                            : type
                    };
                    if (destTable != null &&
                        !NavPropsToSkip.ContainsKey(destTable.GeneratedName + "." + destProp.Name))
                    {
                        destTable.NavigationProperties.Add(destProp);
                    }
                }
            });
            // var isManyToMany = AreAllColumnsForeignKeys
            // The relationship is many-to-many only if the
            // relationship table only contains primary keys
            // of both entities, and no other fields.
            //  0, 1, *: 0-1, 1-0, 1->1, 1<-1, 0-*, 1-*, *-0, *-1, *-*
            //  if 0-1,
            //      add single, non-nullable navigation property
            //      of foreign key destination table class,
            //      and ensure foreign key destination table class
            //      has non-required navigation property to current table class
            //  if 1-0,
            //      do nothing, as non-required navigation property will be added
            //      when processing other side of foreign key relationship
            //  if 1->1,
            //      add single, non-nullable navigation property
            //      of foreign key destination table class,
            //      and ensure foreign key destination table class
            //      has required navigation property to current table class
            //  if 1<-1,
            //      required navigation property will be added
            //      when processing other side of foreign key relationship
            //  if 0-*,
            //      add public virtual ICollection of
            //      foreign key destination table class,
            //      and ensure foreign key destination table class
            //      has non-required navigation property to current table class
            //  if 1-*,
            //      add public virtual ICollection
            //      of foreign key destination table class,
            //      and ensure foreign key destination table class
            //      has required navigation property to current table class
            //  if *-0,
            //      do nothing, as non-required navigation property will be added
            //      when processing other side of foreign key relationship
            //  if *-1,
            //      do nothing, as required navigation property will be added
            //      when processing other side of foreign key relationship
            //  if *-*,
            //      well, there are no such tables, according to the
            //      Entity Framework definition, which is that all columns
            //      in the join table being both in the join table primary key,
            //      and a foreign key pointing from the join table to one of the
            //      joined tables.
            return(props);
        }
Beispiel #2
0
        public static IEnumerable <Table> GenerateAll(
            DataSet ds)
        {
            var tables = DbUtil.GetTables(
                ds.Tables["Columns"],
                ds.Tables["IndexColumns"],
                ds.Tables["Indexes"],
                ds.Tables["Schemas"],
                ds.Tables["Tables"]);

            tables
            .ForEach(a =>
            {
                a.Columns = DbUtil.GetColumnsByTableId(
                    ds.Tables["Columns"],
                    ds.Tables["Types"],
                    ds.Tables["DefaultConstraints"],
                    a.ObjectId,
                    a.TableName);
                a.ForeignKeys = DbUtil.GetForeignKeysByTableId(
                    ds.Tables["Columns"],
                    ds.Tables["ForeignKeys"],
                    ds.Tables["ForeignKeyColumns"],
                    ds.Tables["Tables"],
                    a.ObjectId,
                    a.TableName);
                a.PrimaryKeyColumns = DbUtil.GetColumnsByTableIdColumnId(
                    ds.Tables["Columns"],
                    a.ObjectId,
                    DbUtil.GetIndexColumnsByTableIdIndexId(
                        ds.Tables["IndexColumns"],
                        a.ObjectId,
                        DbUtil.GetPrimaryKeyIndexIdByTableId(
                            ds.Tables["Indexes"],
                            a.ObjectId)));
                a.PrimaryKeyColumns
                .ForEach(b =>
                {
                    if (string.IsNullOrWhiteSpace(b))
                    {
                        return;
                    }
                    var kcol = a.Columns
                               .FirstOrDefault(c => c.Name == b);
                    if (kcol != null)
                    {
                        kcol.IsKey = true;
                    }
                });
                a.ActiveColumnName =
                    DbUtil.HasTableActiveFlag(a)
                        ? DbUtil.GetTableActivityFieldName(a)
                        : null;
                a.ActiveColumnValue =
                    DbUtil.HasTableActiveFlag(a) &&
                    DbUtil.GetTableActivityFieldValue(a);
            });
            tables.ForEach(a =>
            {
                a.NavigationProperties
                .AddRange(GenerateNavigationProperties(
                              ds.Tables["Columns"],
                              ds.Tables["ForeignKeyColumns"],
                              ds.Tables["ForeignKeys"],
                              ds.Tables["Tables"],
                              a,
                              tables));
            });
            return(tables);
        }