Пример #1
0
            public List <String> GetTable(EntityDef r)
            {
                var DuplicatedInMySqlViewPoint = new HashSet <Key>();
                var NondirectionalKeys         = new HashSet <ByIndex>();

                foreach (var k in (new Key[] { r.PrimaryKey }).Concat(r.UniqueKeys).Concat(r.NonUniqueKeys))
                {
                    var Index = new ByIndex {
                        Columns = k.Columns.Select(c => c.Name).ToList()
                    };
                    if (!NondirectionalKeys.Contains(Index))
                    {
                        NondirectionalKeys.Add(Index);
                    }
                    else
                    {
                        DuplicatedInMySqlViewPoint.Add(k);
                    }
                }

                var FieldsAndKeys = new List <List <String> >();

                foreach (var f in r.Fields)
                {
                    if (f.Attribute.OnColumn)
                    {
                        FieldsAndKeys.Add(GetColumnDef(f));
                    }
                }
                var FieldDict = r.Fields.ToDictionary(f => f.Name);

                {
                    var Name = RelationSchemaExtensions.GetLimitedKeyName("PK", String.Format("{0}_{1}", r.CollectionName, r.PrimaryKey.Columns.FriendlyName()), MaxNameLength);
                    foreach (var c in r.PrimaryKey.Columns)
                    {
                        var f = FieldDict[c.Name];
                        if (f.Type.OnOptional)
                        {
                            throw new InvalidOperationException(String.Format("MySQL主键中不支持NULL字段'{0}': {1}", Name, f.Name));
                        }
                    }
                    FieldsAndKeys.Add(GetPrimaryKey(r.PrimaryKey, Name));
                }
                foreach (var k in r.UniqueKeys)
                {
                    if (DuplicatedInMySqlViewPoint.Contains(k))
                    {
                        continue;
                    }
                    var Name = RelationSchemaExtensions.GetLimitedKeyName("UQ", String.Format("{0}_{1}", r.CollectionName, k.Columns.FriendlyName()), MaxNameLength);
                    FieldsAndKeys.Add(GetUniqueKey(k, Name));
                }

                var Options = new List <List <String> >();

                if (WithComment)
                {
                    if (r.Description != "")
                    {
                        Options.Add(new List <String> {
                            "COMMENT " + GetSqlStringLiteral(r.Description)
                        });
                    }
                }

                var NonUniqueKeys = new List <String>();

                foreach (var k in r.NonUniqueKeys)
                {
                    if (DuplicatedInMySqlViewPoint.Contains(k))
                    {
                        continue;
                    }
                    var Name = RelationSchemaExtensions.GetLimitedKeyName("IX", String.Format("{0}_{1}", r.CollectionName, k.Columns.FriendlyName()), MaxNameLength);
                    NonUniqueKeys.AddRange(GetNonUniqueKey(k, Name, r.CollectionName));
                }

                return(GetTemplate("Table").Substitute("Name", r.CollectionName).Substitute("FieldsAndKeys", JoinWithComma(FieldsAndKeys.ToArray())).Substitute("Options", JoinWithComma(Options.ToArray())).Substitute("NonUniqueKeys", NonUniqueKeys));
            }
        public static void VerifyEntityForeignKeys(this Schema s)
        {
            var Entities  = s.Types.Where(t => t.OnEntity).Select(t => t.Entity).ToList();
            var IndexDict = new Dictionary <String, HashSet <ByIndex> >(StringComparer.OrdinalIgnoreCase);

            foreach (var e in Entities)
            {
                var h = new HashSet <ByIndex>();
                foreach (var k in (new Key[] { e.PrimaryKey }).Concat(e.UniqueKeys).Concat(e.NonUniqueKeys))
                {
                    for (int i = 1; i <= k.Columns.Count; i += 1)
                    {
                        var SubIndex = new ByIndex {
                            Columns = k.Columns.Take(i).Select(c => c.Name).ToList()
                        };
                        if (!h.Contains(SubIndex))
                        {
                            h.Add(SubIndex);
                        }
                    }
                }
                IndexDict.Add(e.Name, h);
            }
            foreach (var e in Entities)
            {
                foreach (var a in e.Fields.Where(f => f.Attribute.OnNavigation))
                {
                    String OtherRecordName;
                    if (a.Type.OnTypeRef)
                    {
                        OtherRecordName = a.Type.TypeRef.Value;
                    }
                    else if (a.Type.OnOptional)
                    {
                        OtherRecordName = a.Type.Optional.Value;
                    }
                    else if (a.Type.OnList)
                    {
                        OtherRecordName = a.Type.List.Value;
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }

                    //FK和FNK只需要目标表上的键有索引,RFK和RFNK需要当前表和目标表的键都有索引
                    if (a.Attribute.Navigation.IsReverse)
                    {
                        var ThisIndex = new ByIndex {
                            Columns = a.Attribute.Navigation.ThisKey
                        };
                        var h = IndexDict[e.Name];
                        if (!h.Contains(ThisIndex))
                        {
                            throw new InvalidOperationException(String.Format("ThisKeyIsNotIndex: {0}->{1} FK:{2}={3}", e.Name, OtherRecordName, String.Join(", ", a.Attribute.Navigation.ThisKey), String.Join(", ", a.Attribute.Navigation.OtherKey)));
                        }
                    }
                    {
                        var OtherIndex = new ByIndex {
                            Columns = a.Attribute.Navigation.OtherKey
                        };
                        var h = IndexDict[OtherRecordName];
                        if (!h.Contains(OtherIndex))
                        {
                            throw new InvalidOperationException(String.Format("OtherKeyIsNotIndex: {0}->{1} FK:{2}={3}", e.Name, OtherRecordName, String.Join(", ", a.Attribute.Navigation.ThisKey), String.Join(", ", a.Attribute.Navigation.OtherKey)));
                        }
                    }
                }
            }
        }