Пример #1
0
        public static string Generate(MetadataSrv.Metadata metadataSrv)
        {
            var entityTypes = metadataSrv.EntityTypes.ToList();
            var entitySets  = (from t in metadataSrv.EntityTypes select new { name = t.Value.EntitySetName, entityTypeName = t.Key }).ToList();

            Dictionary <string, string> dbTypeConvert = null;

            switch (metadataSrv.Dialect)
            {
            case "MSSQL":
                dbTypeConvert = new Dictionary <string, string>()
                {
                    { "int", "int" },
                    { "smallint", "short" },
                    { "real", "float" },
                    { "datetime", "DateTime" },
                    { "nvarchar", "string" },
                    { "text", "string" },
                    { "bit", "bool" }
                };
                break;

            case "MYSQL":
                dbTypeConvert = new Dictionary <string, string>()
                {
                    { "int", "int" },
                    { "smallint", "short" },         // or "int"
                    { "float", "float" },
                    { "decimal", "float" },
                    { "mediumint", "int" },
                    { "tinyint", "sbyte" },         // or "byte"
                    { "datetime", "DateTime" },
                    { "timestamp", "DateTime" },
                    { "bit", "bool" },
                    { "char", "string" },
                    { "varchar", "string" },
                    { "text", "string" },
                    { "longtext", "string" },
                    { "enum", "string" },
                    { "set", "string" },
                    { "geometry", "object" },
                    { "year", "ushort" },
                    { "blob", "byte[]" },
                };
                break;

            default:
                throw new Exception("Unknown dialect");
            }

            var br = new BlockWriter();

            br.WriteLine("#pragma warning disable SA1649, SA1128, SA1005, SA1516, SA1402, SA1028, SA1119, SA1507, SA1502, SA1508, SA1122, SA1633, SA1300")
            .WriteLine()
            .WriteLine("//------------------------------------------------------------------------------")
            .WriteLine("//    This code was auto-generated.")
            .WriteLine("//")
            .WriteLine("//    Manual changes to this file may cause unexpected behavior in your application.")
            .WriteLine("//    Manual changes to this file will be overwritten if the code is regenerated.")
            .WriteLine("//------------------------------------------------------------------------------")
            .WriteLine();

            br.WriteLine("using NavyBlueDtos;");
            br.WriteLine("using NavyBlueEntities;");
            br.WriteLine("using Newtonsoft.Json;");
            br.WriteLine("using Newtonsoft.Json.Linq;");
            br.WriteLine("using System;");
            br.WriteLine("using System.Collections.Generic;");
            br.WriteLine("using MetadataSrv = NavyBlueDtos.MetadataSrv;");
            br.WriteLine();

            br.WriteLine("namespace " + metadataSrv.Namespace);
            br.BeginBlock("{");

            //var json = JsonConvert.SerializeObject(result, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore });

            // DataProvider
            br.WriteLine("public interface IDataProvider");
            br.BeginBlock("{")
            .WriteLine("DataService CreateDataServiceInstance();");
            br.EndBlock("}");

            br.WriteLine("public class DataProvider : IDataProvider");
            br.BeginBlock("{")
            .WriteLine("private readonly IDataProviderDto dataProviderDto;")
            .WriteLine();

            br.WriteLine("public DataProvider(IDataProviderDto dataProviderDto)");
            br.BeginBlock("{")
            .WriteLine("this.dataProviderDto = dataProviderDto;");
            br.EndBlock("}");

            br.WriteLine("public DataService CreateDataServiceInstance()");
            br.BeginBlock("{")
            .WriteLine("var dataServiceDto = this.dataProviderDto.CreateDataServiceInstance();")
            .WriteLine("var dataService = new DataService(dataServiceDto);")
            .WriteLine("return dataService;");
            br.EndBlock("}", false);

            br.EndBlock("}");

            // DataService
            br.WriteLine("public class DataService : DataServiceEntity<LocalEntityViews, LocalDtoViews, RemoteEntityViews, RemoteDtoViews>");
            br.BeginBlock("{");
            br.WriteLine("public DataService(DataServiceDto dataServiceDto) : base(dataServiceDto)");
            br.BeginBlock("{");
            br.WriteLine("this.From = new ServiceLocation<LocalEntityViews, LocalDtoViews, RemoteEntityViews, RemoteDtoViews>()");
            br.BeginBlock("{")
            .WriteLine("Local = new ViewType<LocalEntityViews, LocalDtoViews>() { EntityView = new LocalEntityViews(this.DataContext), DtoView = new LocalDtoViews(this.DataContext, dataServiceDto.MetadataSrv) },")
            .WriteLine("Remote = new ViewType<RemoteEntityViews, RemoteDtoViews>() { EntityView = new RemoteEntityViews(dataServiceDto.DataViewDto, this.DataContext), DtoView = new RemoteDtoViews(dataServiceDto.DataViewDto) }");
            br.EndBlock("};", false);
            br.EndBlock("}", false);

            // br.WriteLine("public static DataService CreateDataServiceInstance()");
            // br.BeginBlock("{")
            //     .WriteLine("var connectionString = DataProviderConfig.GetConnectionString();")
            //     .WriteLine("var metadataSrv = DataProviderConfig.GetMetadataSrv();")
            //     .WriteLine("var dataServiceDto = new DataServiceDto(connectionString, metadataSrv);")
            //     .WriteLine("var dataService = new DataService(dataServiceDto);")
            //     .WriteLine("return dataService;");
            // br.EndBlock("}", false);

            br.EndBlock("}");

            // LocalEntityViews
            br.WriteLine("public class LocalEntityViews : LocalEntityViewsBase");
            br.BeginBlock("{");
            br.WriteLine("public LocalEntityViews(DataContext dataContext) : base(dataContext)");
            br.BeginBlock("{");
            foreach (var es in entitySets)
            {
                br.WriteLine(string.Format("//this.[\"{0}\"] = new DataViewLocalEntity<{1}>(dataContext);", es.name, es.entityTypeName));
            }
            br.EndBlock("}");
            foreach (var es in entitySets)
            {
                br.WriteLine(string.Format("public DataViewLocalEntity<{1}> {0} {{ get {{ return this.GetPropertyValue<{1}>(); }} }}", es.name, es.entityTypeName));
            }
            br.EndBlock("}");

            // RemoteEntityViews
            br.WriteLine("public class RemoteEntityViews : RemoteEntityViewsBase");
            br.BeginBlock("{");
            br.WriteLine("public RemoteEntityViews(DataViewDto dataViewDto, DataContext dataContext) : base(dataViewDto, dataContext)");
            br.BeginBlock("{");
            foreach (var es in entitySets)
            {
                br.WriteLine(string.Format("//this.[\"{0}\"] = new DataViewRemoteEntity<{1}>(dataViewDto, dataContext);", es.name, es.entityTypeName));
            }
            br.EndBlock("}");
            foreach (var es in entitySets)
            {
                br.WriteLine(string.Format("public DataViewRemoteEntity<{1}> {0} {{ get {{ return this.GetPropertyValue<{1}>(); }} }}", es.name, es.entityTypeName));
            }
            br.EndBlock("}");

            // LocalDtoViews
            br.WriteLine("public class LocalDtoViews : LocalDtoViewsBase");
            br.BeginBlock("{");
            br.WriteLine("public LocalDtoViews(DataContext dataContext, MetadataSrv.Metadata metadataSrv) : base(dataContext, metadataSrv)");
            br.BeginBlock("{");
            foreach (var es in entitySets)
            {
                br.WriteLine(string.Format("//this.[\"{0}\"] = new DataViewLocalDto<{1}>(dataContext, metadataSrv);", es.name, es.entityTypeName));
            }
            br.EndBlock("}");
            foreach (var es in entitySets)
            {
                br.WriteLine(string.Format("public DataViewLocalDto<{1}> {0} {{ get {{ return this.GetPropertyValue<{1}>(); }} }}", es.name, es.entityTypeName));
            }
            br.EndBlock("}");

            // RemoteDtoViews
            br.WriteLine("public class RemoteDtoViews : RemoteDtoViewsBase");
            br.BeginBlock("{");
            br.WriteLine("public RemoteDtoViews(DataViewDto dataViewDto) : base(dataViewDto)");
            br.BeginBlock("{");
            foreach (var es in entitySets)
            {
                br.WriteLine(string.Format("//this.[\"{0}\"] = new DataViewRemoteDto<{1}>(dataViewDto);", es.name, es.entityTypeName));
            }
            br.EndBlock("}");
            foreach (var es in entitySets)
            {
                br.WriteLine(string.Format("public DataViewRemoteDto {0} {{ get {{ return this.GetPropertyValue(\"{1}\"); }} }}", es.name, es.entityTypeName));
            }
            br.EndBlock("}");

            // Entities
            foreach (var et in entityTypes)
            {
                var entityTypeName       = et.Key;
                var properties           = et.Value.Properties;
                var navigationProperties = et.Value.NavigationProperties ?? new Dictionary <string, MetadataSrv.NavigationProperty>();

                // with constructor generator
                br.WriteLine(string.Format("public sealed class {0} : IDerivedEntity", entityTypeName));
                br.BeginBlock("{");
                br.WriteLine(string.Format("public {0}(Entity entity)", entityTypeName));
                br.BeginBlock("{")
                .WriteLine(string.Format("if (entity.entityTypeName != \"{0}\") {{ throw new ArgumentException(\"Incorrect entity type\"); }}", entityTypeName))
                .WriteLine("this.entity = entity;");
                br.EndBlock("}");

                br.WriteLine("public Entity entity { get; private set; }")
                .WriteLine();

                GeneratorUtils.WriteProperties(br, properties, dbTypeConvert);

                // navigation properties for intellisense
                GeneratorUtils.WriteNavigationProperties(br, entityTypeName, navigationProperties);

                br.EndBlock("}");
            }

            br.EndBlock("}");

            br.WriteLine("#pragma warning restore SA1649, SA1128, SA1005, SA1516, SA1402, SA1028, SA1119, SA1507, SA1502, SA1508, SA1122, SA1633, SA1300");

            return(br.ToString());
        }
        public static MetadataSrv.Metadata Generate()
        {
            var db = new DatabaseOperations("MYSQL", @"Server=localhost;Database=sakila;Uid=root;Pwd=Pass@word1;");

            var tableSchema = "sakila";

            var descriptionsSql = "SELECT @@VERSION as Version"; // SELECT VERSION() AS Version;
            var descriptions    = db.Query <DatabaseTypes.Description>(descriptionsSql);

            var tablesSql = string.Format("SELECT TABLE_NAME AS Name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME <> 'sysdiagrams' AND TABLE_SCHEMA = '{0}' AND TABLE_TYPE != 'VIEW';", tableSchema);
            var tables    = db.Query <DatabaseTypes.Table>(tablesSql);

            var columnsSql = string.Format("SELECT c.TABLE_NAME AS 'Table', c.COLUMN_NAME AS Name, CASE c.COLUMN_TYPE WHEN 'tinyint(1)' THEN 'bit' ELSE c.DATA_TYPE END AS Type, c.COLUMN_DEFAULT AS 'Default', c.CHARACTER_MAXIMUM_LENGTH AS MaxLength, CASE c.IS_NULLABLE WHEN 'NO' THEN 0 WHEN 'YES' THEN 1 END AS IsNullable, CASE WHEN cu.COLUMN_NAME IS NULL THEN 0 ELSE 1 END AS IsKey, CASE c.EXTRA WHEN 'auto_increment' THEN 1 ELSE 0 END AS IsIdentity FROM INFORMATION_SCHEMA.COLUMNS AS c LEFT JOIN (SELECT t.TABLE_SCHEMA, t.TABLE_NAME, k.COLUMN_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS t LEFT JOIN INFORMATION_SCHEMA.key_column_usage AS k USING(constraint_name, table_schema, table_name) WHERE t.CONSTRAINT_TYPE='PRIMARY KEY') AS cu ON cu.TABLE_SCHEMA = c.TABLE_SCHEMA AND cu.TABLE_NAME = c.TABLE_NAME AND cu.COLUMN_NAME = c.COLUMN_NAME WHERE c.TABLE_SCHEMA = '{0}' ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION;", tableSchema);
            var allColumns = db.Query <DatabaseTypes.Column>(columnsSql);

            var relationsSql = string.Format("SELECT cu.CONSTRAINT_NAME AS ForeignKeyName, cu.TABLE_NAME AS ParentTable, cu.COLUMN_NAME AS ParentColumnName, c.ORDINAL_POSITION AS ParentColumnId, cu.REFERENCED_TABLE_NAME AS ReferencedTable, cu.REFERENCED_COLUMN_NAME AS ReferencedColumnName FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS cu INNER JOIN INFORMATION_SCHEMA.COLUMNS AS c ON cu.TABLE_SCHEMA = c.TABLE_SCHEMA AND cu.TABLE_NAME = c.TABLE_NAME AND cu.COLUMN_NAME = c.COLUMN_NAME WHERE cu.TABLE_SCHEMA = '{0}' AND cu.REFERENCED_TABLE_NAME IS NOT NULL ORDER BY c.ORDINAL_POSITION;", tableSchema);
            var allRelations = db.Query <DatabaseTypes.Relation>(relationsSql);

            var originalTableName = new Dictionary <string, string>();

            // corect table names everywere
            foreach (var tbl in tables)
            {
                var transformedTableName = tbl.Name.CamelCase();
                originalTableName[transformedTableName] = tbl.Name;
                tbl.Name = transformedTableName;
            }

            // corect table names everywere
            foreach (var col in allColumns)
            {
                col.Table = col.Table.CamelCase();
            }

            // corect table names everywere
            foreach (var rel in allRelations)
            {
                rel.ParentTable     = rel.ParentTable.CamelCase();
                rel.ReferencedTable = rel.ReferencedTable.CamelCase();
            }

            var entityTypes = new Dictionary <string, MetadataSrv.EntityType>();

            var tableNames = new Dictionary <string, string>();

            foreach (var table in tables)
            {
                var entityTypeName = table.Name.Singularize();
                var entitySetName  = entityTypeName.Pluralize();

                tableNames.Add(entityTypeName, table.Name);

                var tableName = originalTableName[table.Name];

                var columns = allColumns.Where((it) => it.Table == table.Name);

                var key = (from t in columns where t.IsKey.ToBoolean() select t.Name.CamelCase()).ToArray();

                var properties = (from t in columns select t).ToDictionary(col => col.Name.CamelCase(), col => new MetadataSrv.Property()
                {
                    FieldName = col.Name,
                    Type      = col.Type,
                    Nullable  = col.IsNullable.ToBoolean(),
                    Default   = GeneratorUtils.GetDefaultValue(col),
                    MaxLength = (int?)col.MaxLength
                });

                var calculatedProperties = (from t in columns where t.IsComputed.ToBoolean() || t.IsIdentity.ToBoolean() select t.Name.CamelCase()).ToArray();

                var entityType = new MetadataSrv.EntityType()
                {
                    TableName            = tableName,
                    EntitySetName        = entitySetName,
                    Key                  = key,
                    Properties           = properties,
                    CalculatedProperties = calculatedProperties,
                    NavigationProperties = new Dictionary <string, MetadataSrv.NavigationProperty>(),
                };

                entityTypes.Add(entityTypeName, entityType);
            }

            foreach (var et in entityTypes)
            {
                var entityTypeName = et.Key;
                var entityType     = et.Value;

                var relationsCorrected = allRelations.Where((it) => it.ParentTable == tableNames[entityTypeName]);

                var relations = from t in relationsCorrected
                                group t by t.ForeignKeyName into g
                                select new
                {
                    foreignKey             = g.Key,
                    parentTable            = g.FirstOrDefault().ParentTable.Singularize(),
                    referencedTable        = g.FirstOrDefault().ReferencedTable.Singularize(),
                    referentialConstraints = (from r in g
                                              select new
                    {
                        property = r.ParentColumnName,
                        referencedProperty = r.ReferencedColumnName
                    }).ToList()
                };

                var proposedName = string.Empty;

                foreach (var relation in relations)
                {
                    var keyLocal  = relation.referentialConstraints.Select((it) => it.property.CamelCase()).ToArray();
                    var keyRemote = relation.referentialConstraints.Select((it) => it.referencedProperty.CamelCase()).ToArray();

                    proposedName = entityType.NavigationProperties.GetNavigationPropertyName(relation.referencedTable);
                    entityType.NavigationProperties.Add(proposedName, new MetadataSrv.NavigationProperty()
                    {
                        EntityTypeName = relation.referencedTable,
                        Multiplicity   = "single",
                        KeyLocal       = keyLocal,
                        KeyRemote      = keyRemote
                    });

                    var entityTypeReferenced = entityTypes[relation.referencedTable];
                    proposedName = entityTypeReferenced.NavigationProperties.GetNavigationPropertyName(relation.parentTable.Pluralize());
                    entityTypeReferenced.NavigationProperties.Add(proposedName, new MetadataSrv.NavigationProperty()
                    {
                        EntityTypeName = relation.parentTable,
                        Multiplicity   = "multi",
                        KeyLocal       = keyRemote,
                        KeyRemote      = keyLocal
                    });
                }
            }

            var description = descriptions.FirstOrDefault().Version.Split(new char[] { '(', '-' }).FirstOrDefault().Trim();

            var metadataSrv = new MetadataSrv.Metadata
            {
                Dialect      = "MYSQL",
                Version      = "v0.0.1",
                Description  = description,
                Namespace    = "Server.Models.DataAccess",
                Multiplicity = new MetadataSrv.Multiplicity()
                {
                    Multi  = "multi",
                    Single = "single"
                },
                EntityTypes = entityTypes
            };

            return(metadataSrv);
        }