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); }