public static SqlBuilder ToSqlBuilder(this MetadataColumn ForeignKeyColumn)
        {
            MetadataForeignKey FK      = ForeignKeyColumn.Parent.FindForeignKeys(ForeignKeyColumn).First();
            MetadataTable      PK      = SqlBuilder.DefaultMetadata.FindTable(FK.ReferencedSchema + "." + FK.ReferencedTable);
            string             namecol = PK.GuessTitleColumn();

            string[] valuecols = FK.ColumnReferences.Where(x => !x.Column.IsComputed).Select(x => x.ReferencedColumn.Name).ToArray();

            SqlBuilder Builder = SqlBuilder.Select()
                                 .From(PK.Name, null, PK.Schema)
                                 .Column(namecol)
                                 .Columns(valuecols)
                                 .Builder();
            List <MetadataColumnReference> mcrs = FK.ColumnReferences.Where(x => x.Column.IsComputed).ToList();

            if (mcrs.Count > 0)
            {
                MetadataColumnReference first = mcrs.First();
                Builder.From(PK.Name, null, PK.Schema)
                .Where(PK.Name, first.ReferencedColumn.Name, SqlOperators.Equal, (object)first.Column.Name.Trim('\"'))
                .Builder();
                foreach (MetadataColumnReference mcr in mcrs.Skip(1))
                {
                    Builder.From(PK.Name, null, PK.Schema)
                    .Where(PK.Name, mcr.ReferencedColumn.Name, SqlOperators.Equal, (object)mcr.Column.Name.Trim('\"'))
                    .Builder();
                }
            }


            return(Builder);
        }
Пример #2
0
 private void BuildVirtualKeys(List<VirtualForeignKey> keys, MetadataTable mt, MetadataDatabase mdb, bool PrimaryKeyIndexOnly)
 {
     foreach (VirtualForeignKey vfk in keys)
     {
         MetadataForeignKey mfk = new MetadataForeignKey()
         {
             ID = 0,
             Name = vfk.values[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0],
             ReferencedKey = "",
             ReferencedTable = vfk.values[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[1],
             ReferencedSchema = vfk.values[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[2],
             Parent = mt,
             IsVirtual = true
         };
         MetadataTable mtref = null;
         if (!mdb.Tables.TryGetValue(mfk.ReferencedSchema + "." + mfk.ReferencedTable, out mtref))
         {
             bool self = false;
             if (mfk.ReferencedSchema == mt.Schema && mfk.ReferencedTable == mt.Name)
             {
                 self = true;
             }
             mtref = BuildMetadata(mdb, mfk.ReferencedTable, mfk.ReferencedSchema, PrimaryKeyIndexOnly, self);
         }
         for (int i = 1; i < vfk.values.Length; i++)
         {
             MetadataColumnReference mcf = new MetadataColumnReference()
             {
                 ReferencedColumn = mtref[vfk.values[i].Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[1]],
             };
             string from = vfk.values[i].Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[0];
             if (from.StartsWith("\""))
             {
                 MetadataColumn mcVirtual = new MetadataColumn()
                 {
                     Name = from,
                     IsForeignKey = true,
                     ID = 0,
                     SqlDataType = SqlDbType.NVarChar,
                     Nullable = false,
                     Length = 0,
                     IsComputed = true,
                     DataType = typeof(string),
                 };
                 mcf.Column = mcVirtual;
                 mcf.Name = from;
             }
             else
             {
                 mcf.Column = mt[from];
                 mcf.Name = mcf.Column.Name;
             }
             mfk.ColumnReferences.Add(mcf);
         }
         mt.ForeignKeys.AddOrUpdate(mfk.Name, mfk, (k, v) => { return mfk; });
     }
 }
        private static JoinConditionGroup To(SqlBuilder Builder, Table FromSqlTable, MetadataTable FromTable, MetadataColumn FromField, MetadataTable ToTable, Join.JoinTypes JoinType, bool PreferForeignKeyOverPrimaryKey = true)
        {
            MetadataDatabase          mdb = Builder.Metadata;
            List <MetadataForeignKey> Fks = null;
            MetadataForeignKey        FK  = null;
            Join j = null;
            MetadataColumnReference mcr = null;
            JoinConditionGroup      jcg = null;

            if (FromField.IsPrimaryKey)
            {
                if (!FromField.IsForeignKey || !PreferForeignKeyOverPrimaryKey)
                {
                    Fks = ToTable.ForeignKeys.Values.Where(x => x.ReferencedTable.Equals(FromTable.Name) && x.ReferencedSchema.Equals(FromTable.Schema) && x.ColumnReferences.Any(y => y.ReferencedColumn.Equals(FromField))).ToList();
                    if (Fks.Count != 1)
                    {
                        throw new InvalidOperationException(string.Format("The column '{0}' is referenced by {1} keys in the table {2}. Expected 1. Make the join manually",
                                                                          FromField.Name, Fks.Count, ToTable.Fullname));
                    }
                    FK = Fks.First();
                    j  = SqlStatementExtensions.MakeJoin(JoinType, FromSqlTable, ToTable.Name, null, ToTable.Schema.Equals("dbo") ? null : ToTable.Schema);

                    mcr = FK.ColumnReferences.First();
                    jcg = j.On(FromField.Name, SqlOperators.Equal, mcr.Name);
                    return(jcg);
                }
            }
            if (FromField.IsForeignKey)
            {
                Fks = new List <MetadataForeignKey>(FromTable.FindForeignKeys(FromField, ToTable.Name));
                if (Fks.Count != 1)
                {
                    throw new InvalidOperationException(string.Format("The column '{0}' resolves to {1} keys in the table {2}. Expected 1. Make the join manually",
                                                                      FromField.Name, Fks.Count, ToTable.Fullname));
                }
                FK  = Fks.First();
                j   = SqlStatementExtensions.MakeJoin(JoinType, FromSqlTable, ToTable.Name, null, ToTable.Schema.Equals("dbo") ? null : ToTable.Schema);
                mcr = FK.ColumnReferences.First();
                jcg = j.On(FromField.Name, SqlOperators.Equal, mcr.ReferencedColumn.Name);

                if (FK.ColumnReferences.Count > 1)
                {
                    foreach (MetadataColumnReference mcr2 in FK.ColumnReferences.Skip(1))
                    {
                        if (mcr2.Name.StartsWith("\""))
                        {
                            // its a value reference
                            // jcg.And(FK.ReferencedTable, mcr2.ReferencedColumn.Name, SqlOperators.Equal, mcr2.Name.Trim('\"'),null);

                            decimal d;
                            object  o;
                            if (decimal.TryParse(mcr2.Name.Trim('\"'), out d))
                            {
                                o = d;
                            }
                            else
                            {
                                o = (object)mcr2.Name.Trim('\"');
                            }

                            jcg.And(mcr2.ReferencedColumn.Name, SqlOperators.Equal, o, null);
                        }
                        else
                        {
                            jcg.And(mcr2.Column.Name, SqlOperators.Equal, mcr2.ReferencedColumn.Name);
                        }
                    }
                }
                return(jcg);
            }
            throw new ArgumentException(string.Format("The Column '{0}' in the table '{1}' must be a foreign key or primary key", FromField.Name, FromTable.Fullname), "FromField");
        }