public void SourceNamespace() { // Verify that we can filter by source namespace. // This should only generate [Class4]. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(FooBar.Class4).Namespace }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); var sourceCode = output.SourceCode; Assert.DoesNotContain("class Class1", sourceCode); Assert.DoesNotContain("class Class2", sourceCode); Assert.DoesNotContain("class Class3", sourceCode); Assert.Contains("class Class4", sourceCode); Assert.DoesNotContain("class Service1", sourceCode); Assert.DoesNotContain("class Service2", sourceCode); }
public void CustomPropertyNames() { // Vertify that [JsonProperty(PropertyName = "xxx")] works. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_DataModel).Namespace, }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); using (var context = new AssemblyContext("Neon.ModelGen.Output", assemblyStream)) { var data = context.CreateDataWrapper <CustomNamesModel>(); Assert.Equal("{\"CustomString\":null,\"CustomInt\":0}", data.ToString()); data["String"] = "Hello World!"; data["Int"] = 1001; Assert.Equal("{\"CustomString\":\"Hello World!\",\"CustomInt\":1001}", data.ToString()); data = context.CreateDataWrapperFrom <CustomNamesModel>(data.ToString()); Assert.Equal("{\"CustomString\":\"Hello World!\",\"CustomInt\":1001}", data.ToString()); } }
public void Filter3AndClient() { // Verify that only those types tagged with [Target("3")] and [Target("client")] // are generated. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_CustomOutput).Namespace, Targets = new List <string>() { "3", "client" } }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); var sourceCode = output.SourceCode; Assert.Contains("class Class1", sourceCode); Assert.Contains("class Class2", sourceCode); Assert.Contains("class Class3", sourceCode); Assert.DoesNotContain("class Class4", sourceCode); Assert.Contains("class Service1", sourceCode); Assert.DoesNotContain("class Service2", sourceCode); }
public void DefaultValues() { // Verify that data models with default property values are initialized correctly. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_DataModel).Namespace, }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); using (var context = new AssemblyContext("Neon.ModelGen.Output", assemblyStream)) { var data = context.CreateDataWrapper <DefaultValues>(); Assert.Equal("Joe Bloe", data["Name"]); Assert.Equal(67, data["Age"]); Assert.Equal(100000.0, data["NetWorth"]); Assert.Equal(MyEnum1.Three, (MyEnum1)data["Enum1"]); } }
public void AllTargets() { // Verify that all types are generated when no targets // are specified. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_CustomOutput).Namespace, }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); var sourceCode = output.SourceCode; Assert.Contains("class Class1", sourceCode); Assert.Contains("class Class2", sourceCode); Assert.Contains("class Class3", sourceCode); Assert.DoesNotContain("class Class4", sourceCode); Assert.Contains("class Service1", sourceCode); Assert.Contains("class Service2", sourceCode); }
private void RefreshModelText(UniversalGenerator uniGen) { try { var list = uniGen.GetColumns(ComboBox_Database.Text, CheckedListBox_DataTable.Text); TextBox_Generated.Text = ModelGenerator.Generate(new ModelSetting() { Using = TextBox_Using.Text.Trim(), Namespace = TextBox_NameSpace.Text.Trim(), TabSpace = NumBox_TabSpace.Value.ToInt(), AccessModifier = ComboBox_AccessModifier.Text.Trim(), Inherit = TextBox_Inherit.Text.Trim(), ModelName = CheckedListBox_DataTable.Text.Trim(), ModelSummary = $"Model: {CheckedListBox_DataTable.Text.Trim()}", UseSummary = CheckBox_UseSummary.Checked, EnableSQLSugarSupport = ToolStripMenuItem_EnableSQLSugarDefaultSupport.Checked, Columns = list, }); } catch (Exception ex) { #if DEBUG Console.WriteLine($@"{ex.Message} {ex.StackTrace}"); #endif Alert.Error(ex.Message); return; } }
public void GenerateIncludeEntities() { var databaseModel = new DatabaseModel { DatabaseName = "TestDatabase", DefaultSchema = "dbo" }; var testTable = GenerateDatabaseTable("TestTable", databaseModel); var otherTable = GenerateDatabaseTable("OtherTable", databaseModel); var generatorOptions = new GeneratorOptions(); //TODO: introduce Include MatchOptions (cfr. Exclude) //generatorOptions.Database.Include.Add(new MatchOptions { Exact = @"dbo.TestTable" }); var generator = new ModelGenerator(NullLoggerFactory.Instance); var typeMappingSource = CreateTypeMappingSource(); var result = generator.Generate(generatorOptions, databaseModel, typeMappingSource); result.ContextClass.Should().Be("TestDatabaseContext"); result.ContextNamespace.Should().Be("TestDatabase.Data"); result.Entities.Count.Should().Be(1); var firstEntity = result.Entities[0]; firstEntity.TableName.Should().Be("TestTable"); firstEntity.TableSchema.Should().Be("dbo"); firstEntity.EntityClass.Should().Be("TestTable"); firstEntity.EntityNamespace.Should().Be("TestDatabase.Data.Entities"); firstEntity.MappingClass.Should().Be("TestTableMap"); firstEntity.MappingNamespace.Should().Be("TestDatabase.Data.Mapping"); }
public void GenerateExcludeEntities() { var databaseModel = new DatabaseModel { DatabaseName = "TestDatabase", DefaultSchema = "dbo" }; var testTable = GenerateDatabaseTable("TestTable", databaseModel); var otherTable = GenerateDatabaseTable("OtherTable", databaseModel); var anotherTable = GenerateDatabaseTable("AnotherTable", databaseModel); var generatorOptions = new GeneratorOptions(); generatorOptions.Database.Exclude.Add(new MatchOptions { Exact = @"dbo.OtherTable" }); var generator = new ModelGenerator(NullLoggerFactory.Instance); var typeMappingSource = CreateTypeMappingSource(); var result = generator.Generate(generatorOptions, databaseModel, typeMappingSource); result.ContextClass.Should().Be("TestDatabaseContext"); result.ContextNamespace.Should().Be("TestDatabase.Data"); result.Entities.Count.Should().Be(2); foreach (var entity in result.Entities) { entity.TableName.Should().NotBe("OtherTable"); } }
public void NoGetter() { // Verify that we can generate code for the [NoGetter] data model. // This has a single property that only has a getter which should // be ignored by the code generator, so this should end up being // equivalent to a model with no properties. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_DataModel).Namespace, }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); using (var context = new AssemblyContext("Neon.ModelGen.Output", assemblyStream)) { var data = context.CreateDataWrapper <NoGetter>(); Assert.Equal("{}", data.ToString()); data = context.CreateDataWrapperFrom <NoGetter>(data.ToString()); Assert.Equal("{}", data.ToString()); data = context.CreateDataWrapperFrom <NoGetter>(data.JObject); Assert.Equal("{}", data.ToString()); } }
public void GenerateWithAllNumberColumnName() { var generatorOptions = new GeneratorOptions(); var databaseModel = new DatabaseModel { DatabaseName = "TestDatabase", DefaultSchema = "dbo" }; var testTable = new DatabaseTable { Database = databaseModel, Name = "TestTable" }; databaseModel.Tables.Add(testTable); var identifierColumn = new DatabaseColumn { Table = testTable, Name = "Id", IsNullable = false, StoreType = "int" }; testTable.Columns.Add(identifierColumn); var numberColumn = new DatabaseColumn { Table = testTable, Name = "404", IsNullable = true, StoreType = "int" }; testTable.Columns.Add(numberColumn); var generator = new ModelGenerator(NullLoggerFactory.Instance); var result = generator.Generate(generatorOptions, databaseModel); result.ContextClass.Should().Be("TestDatabaseContext"); result.ContextNamespace.Should().Be("TestDatabase.Data"); result.Entities.Count.Should().Be(1); var firstEntity = result.Entities[0]; firstEntity.EntityClass.Should().Be("TestTable"); firstEntity.EntityNamespace.Should().Be("TestDatabase.Data.Entities"); firstEntity.Properties.Count.Should().Be(2); var identifierProperty = firstEntity.Properties.ByColumn("Id"); identifierProperty.Should().NotBeNull(); identifierProperty.PropertyName.Should().Be("Id"); var numberProperty = firstEntity.Properties.ByColumn("404"); numberProperty.Should().NotBeNull(); numberProperty.PropertyName.Should().Be("Number404"); }
public void NullableProperties() { // NOTE: // // This test doesn't work due to apparent limitations of // the DataWrapper class an perhaps .NET itself. The problem // is related to assigning a nullable Enum value. This // fails even though I explicitly cast the value to (MyEnum1?). // // I think the problem is related to the JIT compiler doing some // magic here and effectively stripping out the cast and // just passing the non-nullable enum value and then // [DataWrapper] fails when dynamically assigning the value // to the property because the value is no longer a (MyEnum1?). // // I have verified this manually when using the generated // model classes directly. // Verify that we handle nullable property types correctly. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_UxDataModel).Namespace, UxFramework = UxFrameworks.Xaml }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); using (var context = new AssemblyContext("Neon.ModelGen.Output", assemblyStream)) { var data = context.CreateDataWrapper <NullableProperties>(); Assert.Equal("{\"Bool\":null,\"Int\":null,\"Enum\":null}", data.ToString()); data = context.CreateDataWrapperFrom <NullableProperties>(data.ToString()); Assert.Equal("{\"Bool\":null,\"Int\":null,\"Enum\":null}", data.ToString()); data["Bool"] = true; data["Int"] = 100; data["Enum"] = (MyEnum1?)MyEnum1.Two; // This throws an exception var s = data.ToString(); Assert.Equal("", data.ToString()); } }
public void GenerateModelsCheckNames() { var generatorOptions = new GeneratorOptions(); generatorOptions.Model.Read.Generate = true; generatorOptions.Model.Create.Generate = true; generatorOptions.Model.Update.Generate = true; generatorOptions.Model.Validator.Generate = true; generatorOptions.Model.Mapper.Generate = true; var databaseModel = new DatabaseModel { DatabaseName = "TestDatabase", DefaultSchema = "dbo" }; var testTable = GenerateDatabaseTable("TestTable", databaseModel); var generator = new ModelGenerator(NullLoggerFactory.Instance); var typeMappingSource = CreateTypeMappingSource(); var result = generator.Generate(generatorOptions, databaseModel, typeMappingSource); result.ContextClass.Should().Be("TestDatabaseContext"); result.ContextNamespace.Should().Be("TestDatabase.Data"); result.Entities.Count.Should().Be(1); var firstEntity = result.Entities[0]; firstEntity.TableName.Should().Be("TestTable"); firstEntity.TableSchema.Should().Be("dbo"); firstEntity.EntityClass.Should().Be("TestTable"); firstEntity.EntityNamespace.Should().Be("TestDatabase.Data.Entities"); firstEntity.MappingClass.Should().Be("TestTableMap"); firstEntity.MappingNamespace.Should().Be("TestDatabase.Data.Mapping"); firstEntity.MapperClass.Should().Be("TestTableProfile"); firstEntity.MapperNamespace.Should().Be("TestDatabase.Domain.Mapping"); firstEntity.Properties.Count.Should().Be(2); firstEntity.Models.Count.Should().Be(3); var firstModel = firstEntity.Models[0]; firstModel.ModelClass.Should().StartWith("TestTable"); firstModel.ModelClass.Should().EndWith("Model"); firstModel.ModelNamespace.Should().Be("TestDatabase.Domain.Models"); firstModel.ValidatorClass.Should().StartWith("TestTable"); firstModel.ValidatorClass.Should().EndWith("Validator"); firstModel.ValidatorNamespace.Should().Be("TestDatabase.Domain.Validation"); }
public void EmptyPersistable() { // Verify that we can generate code for an empty data model. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_UxDataModel).Namespace, UxFramework = UxFrameworks.Xaml }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); using (var context = new AssemblyContext("Neon.ModelGen.Output", assemblyStream)) { var data = context.CreateDataWrapper <EmptyPersistableData>(); Assert.Equal("{\"__T\":\"TestModelGen.UxDataModel.EmptyPersistableData\"}", data.ToString()); data = context.CreateDataWrapperFrom <EmptyPersistableData>(data.ToString()); Assert.Equal("{\"__T\":\"TestModelGen.UxDataModel.EmptyPersistableData\"}", data.ToString()); data = context.CreateDataWrapperFrom <EmptyPersistableData>(data.ToJObject()); Assert.Equal("{\"__T\":\"TestModelGen.UxDataModel.EmptyPersistableData\"}", data.ToString()); //------------------------------------------------------------- // Verify Equals(): var value1 = context.CreateDataWrapperFrom <EmptyPersistableData>(data.ToJObject()); var value2 = context.CreateDataWrapperFrom <EmptyPersistableData>(data.ToJObject()); Assert.True(value1.Equals(value1)); Assert.True(value1.Equals(value2)); Assert.True(value2.Equals(value1)); Assert.False(value1.Equals(null)); Assert.False(value1.Equals("Hello World!")); } }
private void RefreshTestModel() { TextBox_Generated.Text = ModelGenerator.Generate(new ModelSetting() { Using = TextBox_Using.Text.Trim(), Namespace = TextBox_NameSpace.Text.Trim(), TabSpace = NumBox_TabSpace.Value.ToInt(), AccessModifier = ComboBox_AccessModifier.Text.Trim(), Inherit = TextBox_Inherit.Text.Trim(), ModelName = "TestEntity", ModelSummary = "Model: TestEntity", UseSummary = CheckBox_UseSummary.Checked, EnableSQLSugarSupport = ToolStripMenuItem_EnableSQLSugarDefaultSupport.Checked, Columns = new List <ColumnInfo> { new ColumnInfo { IsPrimaryKey = true, Name = "TestID", Type = "int", IsNullable = false, Summary = "测试主键" }, new ColumnInfo { IsPrimaryKey = false, Name = "TestNumber", Type = "float", IsNullable = true, Summary = "测试值" }, new ColumnInfo { IsPrimaryKey = false, Name = "TestString", Type = "varchar", IsNullable = true, Summary = "测试字符串" }, } }); }
public void TargetNamespace() { // Verify that we can customize the output namespace. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_CustomOutput).Namespace, TargetNamespace = "Foo.Bar" }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); var sourceCode = output.SourceCode; Assert.Contains("namespace Foo.Bar", sourceCode); }
public void Can_generate_models_from_schema() { var schema = new Schema { Name = "Customer" }; schema.Properties.Add(new SchemaProperty { Name = "Name", Type = "string" }); var ns = new Namespace(Constants.DefaultNamespace); var sb = new IndentAwareStringBuilder(); var models = new ModelGenerator(); models.Generate(sb, ns, 1, schema); sb.InsertAutoGeneratedHeader(); _output.WriteLine(sb.ToString()); }
public void GenerateCheckNames() { var generatorOptions = new GeneratorOptions(); var databaseModel = new DatabaseModel { DatabaseName = "TestDatabase", DefaultSchema = "dbo" }; var testTable = GenerateDatabaseTable("TestTable", databaseModel); var generator = new ModelGenerator(NullLoggerFactory.Instance); var typeMappingSource = CreateTypeMappingSource(); var result = generator.Generate(generatorOptions, databaseModel, typeMappingSource); result.ContextClass.Should().Be("TestDatabaseContext"); result.ContextNamespace.Should().Be("TestDatabase.Data"); result.Entities.Count.Should().Be(1); var firstEntity = result.Entities[0]; firstEntity.TableName.Should().Be("TestTable"); firstEntity.TableSchema.Should().Be("dbo"); firstEntity.EntityClass.Should().Be("TestTable"); firstEntity.EntityNamespace.Should().Be("TestDatabase.Data.Entities"); firstEntity.MappingClass.Should().Be("TestTableMap"); firstEntity.MappingNamespace.Should().Be("TestDatabase.Data.Mapping"); firstEntity.Properties.Count.Should().Be(2); var identifierProperty = firstEntity.Properties.ByColumn("Id"); identifierProperty.Should().NotBeNull(); identifierProperty.PropertyName.Should().Be("Id"); var nameProperty = firstEntity.Properties.ByColumn("Name"); nameProperty.Should().NotBeNull(); nameProperty.PropertyName.Should().Be("Name"); }
public void NotEqualsOperator() { // Verify that the generated binary "==" operator works. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_UxDataModel).Namespace, UxFramework = UxFrameworks.Xaml }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); using (var context = new AssemblyContext("Neon.ModelGen.Output", assemblyStream)) { var value1 = context.CreateDataWrapper <SimpleData>(); var value2 = context.CreateDataWrapper <SimpleData>(); value1["Name"] = "Jeff"; value1["Age"] = 58; value1["Enum"] = MyEnum1.One; value2["Name"] = "Jeff"; value2["Age"] = 58; value2["Enum"] = MyEnum1.One; Assert.False(DataWrapper.NotEquals <SimpleData>(value1, value1)); Assert.False(DataWrapper.NotEquals <SimpleData>(value1, value2)); Assert.True(DataWrapper.NotEquals <SimpleData>(null, value2)); Assert.True(DataWrapper.NotEquals <SimpleData>(value1, null)); value2["Name"] = "Bob"; Assert.True(DataWrapper.NotEquals <SimpleData>(value1, value2)); Assert.True(DataWrapper.NotEquals <SimpleData>(value2, value1)); } }
public void GenerateWithSymbolInDatabaseName() { var generatorOptions = new GeneratorOptions(); var databaseModel = new DatabaseModel { DatabaseName = "Test+Symbol", DefaultSchema = "dbo" }; var databaseTable = new DatabaseTable { Database = databaseModel, Name = "Test+Error", Schema = "dbo" }; databaseModel.Tables.Add(databaseTable); var databaseColumn = new DatabaseColumn { Table = databaseTable, Name = "Id", IsNullable = false, StoreType = "int" }; databaseTable.Columns.Add(databaseColumn); var generator = new ModelGenerator(NullLoggerFactory.Instance); var typeMappingSource = CreateTypeMappingSource(); var result = generator.Generate(generatorOptions, databaseModel, typeMappingSource); result.ContextClass.Should().Be("TestSymbolContext"); result.ContextNamespace.Should().Be("TestSymbol.Data"); result.Entities.Count.Should().Be(1); result.Entities[0].EntityClass.Should().Be("TestError"); result.Entities[0].EntityNamespace.Should().Be("TestSymbol.Data.Entities"); }
public void ReadOnlyCollections() { // Verify serializing read-only collection properties. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_DataModel).Namespace, }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); using (var context = new AssemblyContext("Neon.ModelGen.Output", assemblyStream)) { var data = context.CreateDataWrapper <ReadOnlyCollectionsModel>(); data["Collection"] = new ReadOnlyCollection <string>(new List <string> { "one", "two", "three" }); data["Dictionary"] = new ReadOnlyDictionary <string, string>(new Dictionary <string, string>() { { "one", "1" } }); data = context.CreateDataWrapperFrom <ReadOnlyCollectionsModel>(data.ToString()); Assert.Equal(new List <string> { "one", "two", "three" }, data["Collection"]); Assert.Equal(new Dictionary <string, string>() { { "one", "1" } }, data["Dictionary"]); } }
public void ListOfList() { // Verify serializing a list of lists. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_DataModel).Namespace, }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); using (var context = new AssemblyContext("Neon.ModelGen.Output", assemblyStream)) { var data = context.CreateDataWrapper <ListOfListModel>(); var list = new List <List <string> >(); list.Add(new List <string>() { "zero", "one", "two" }); list.Add(new List <string>() { "three", "four", "five" }); data["List"] = list; data = context.CreateDataWrapperFrom <ListOfListModel>(data.ToString()); Assert.Equal(list, data["List"]); } }
public void Generate(ProfileOptions options, DatabaseModel databaseModel, ITemplatesConfig templates, CodeGeneratorWriter writer) { Options = options ?? throw new ArgumentNullException(nameof(options)); Templates = templates ?? throw new ArgumentNullException(nameof(templates)); var databaseProviders = GetDatabaseProviders(); _logger.LogInformation("Loaded database model for: {databaseName}", databaseModel.DatabaseName); var context = _modelGenerator.Generate(Options, databaseModel, databaseProviders.mapping); //var topTemplatesPath = Path.GetFullPath(Path.Combine(Options.Options.ProfilePath, "templates")); //_topTemplates = Directory.GetFiles(topTemplatesPath, "*.scriban-cs", SearchOption.TopDirectoryOnly); //var childTemplatesPath = Path.GetFullPath(Path.Combine(topTemplatesPath, "entities")); //_entityTemplates = Directory.GetFiles(childTemplatesPath, "*.scriban-cs", SearchOption.TopDirectoryOnly); //childTemplatesPath = Path.GetFullPath(Path.Combine(topTemplatesPath, "entities/models")); //_entityModelTemplates = Directory.GetFiles(childTemplatesPath, "*.scriban-cs", SearchOption.TopDirectoryOnly); GenerateFiles(context, writer); }
public void GenerateMultipleEntities() { var databaseModel = new DatabaseModel { DatabaseName = "TestDatabase", DefaultSchema = "dbo" }; var testTable = GenerateDatabaseTable("TestTable", databaseModel); var otherTable = GenerateDatabaseTable("OtherTable", databaseModel); var generatorOptions = new GeneratorOptions(); var generator = new ModelGenerator(NullLoggerFactory.Instance); var typeMappingSource = CreateTypeMappingSource(); var result = generator.Generate(generatorOptions, databaseModel, typeMappingSource); result.ContextClass.Should().Be("TestDatabaseContext"); result.ContextNamespace.Should().Be("TestDatabase.Data"); result.Entities.Count.Should().Be(2); }
public void NoServices() { // Verify that we can disable service client generation. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_CustomOutput).Namespace, NoServiceClients = true }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); var sourceCode = output.SourceCode; Assert.Contains("class Class1", sourceCode); Assert.Contains("class Class2", sourceCode); Assert.Contains("class Class3", sourceCode); Assert.DoesNotContain("class Service1", sourceCode); Assert.DoesNotContain("class Service2", sourceCode); }
public void GenerateCheckNameCase() { var generatorOptions = new GeneratorOptions(); var databaseModel = new DatabaseModel { DatabaseName = "TestDatabase", DefaultSchema = "dbo" }; var testTable = new DatabaseTable { Database = databaseModel, Name = "aammstest", Schema = "dbo" }; databaseModel.Tables.Add(testTable); var identifierColumn = new DatabaseColumn { Table = testTable, Name = "Id", IsNullable = false, StoreType = "int" }; testTable.Columns.Add(identifierColumn); var nameColumn = new DatabaseColumn { Table = testTable, Name = "Name", IsNullable = true, StoreType = "varchar(50)" }; testTable.Columns.Add(nameColumn); var generator = new ModelGenerator(NullLoggerFactory.Instance); var typeMappingSource = CreateTypeMappingSource(); var result = generator.Generate(generatorOptions, databaseModel, typeMappingSource); result.ContextClass.Should().Be("TestDatabaseContext"); result.ContextNamespace.Should().Be("TestDatabase.Data"); result.Entities.Count.Should().Be(1); var firstEntity = result.Entities[0]; firstEntity.TableName.Should().Be("aammstest"); firstEntity.TableSchema.Should().Be("dbo"); firstEntity.EntityClass.Should().Be("Aammstest"); firstEntity.EntityNamespace.Should().Be("TestDatabase.Data.Entities"); firstEntity.MappingClass.Should().Be("AammstestMap"); firstEntity.MappingNamespace.Should().Be("TestDatabase.Data.Mapping"); firstEntity.Properties.Count.Should().Be(2); var identifierProperty = firstEntity.Properties.ByColumn("Id"); identifierProperty.Should().NotBeNull(); identifierProperty.PropertyName.Should().Be("Id"); var nameProperty = firstEntity.Properties.ByColumn("Name"); nameProperty.Should().NotBeNull(); nameProperty.PropertyName.Should().Be("Name"); }
public void GenerateWithEnumMappings() { var generatorOptions = new GeneratorOptions(); generatorOptions.Data.Entity.PrefixWithSchemaName = true; generatorOptions.Data.Entity.EnumMappings = new Dictionary <string, string> { { "tst.TestTable.TestEnumType", "My.NameSpace.MyTestEnum" } }; var databaseModel = new DatabaseModel { DatabaseName = "TestDatabase", DefaultSchema = "dbo" }; var testTableDbo = new DatabaseTable { Database = databaseModel, Name = "TestTable", Schema = "dbo" }; var testTableTst = new DatabaseTable { Database = databaseModel, Name = "TestTable", Schema = "tst" }; databaseModel.Tables.Add(testTableDbo); databaseModel.Tables.Add(testTableTst); var identifierColumnDbo = new DatabaseColumn { Table = testTableDbo, Name = "Id", IsNullable = false, StoreType = "int" }; var identifierColumnTst = new DatabaseColumn { Table = testTableTst, Name = "Id", IsNullable = false, StoreType = "int" }; testTableDbo.Columns.Add(identifierColumnDbo); testTableTst.Columns.Add(identifierColumnTst); var nameColumnDbo = new DatabaseColumn { Table = testTableDbo, Name = "Name", IsNullable = true, StoreType = "varchar(50)" }; var enumColumnTst = new DatabaseColumn { Table = testTableTst, Name = "TestEnumType", IsNullable = true, StoreType = "int" }; testTableDbo.Columns.Add(nameColumnDbo); testTableTst.Columns.Add(enumColumnTst); var generator = new ModelGenerator(NullLoggerFactory.Instance); var typeMappingSource = CreateTypeMappingSource(); var result = generator.Generate(generatorOptions, databaseModel, typeMappingSource); result.ContextClass.Should().Be("TestDatabaseContext"); result.ContextNamespace.Should().Be("TestDatabase.Data"); result.Entities.Count.Should().Be(2); var firstEntity = result.Entities[0]; firstEntity.TableName.Should().Be("TestTable"); firstEntity.TableSchema.Should().Be("dbo"); firstEntity.EntityClass.Should().Be("DboTestTable"); firstEntity.EntityNamespace.Should().Be("TestDatabase.Data.Entities"); firstEntity.MappingClass.Should().Be("DboTestTableMap"); firstEntity.MappingNamespace.Should().Be("TestDatabase.Data.Mapping"); var secondEntity = result.Entities[1]; secondEntity.TableName.Should().Be("TestTable"); secondEntity.TableSchema.Should().Be("tst"); secondEntity.EntityClass.Should().Be("TstTestTable"); secondEntity.EntityNamespace.Should().Be("TestDatabase.Data.Entities"); secondEntity.MappingClass.Should().Be("TstTestTableMap"); secondEntity.MappingNamespace.Should().Be("TestDatabase.Data.Mapping"); secondEntity.Properties.First(x => x.PropertyName == "TestEnumType").EnumTypeName.Should().Be("My.NameSpace.MyTestEnum"); }
private void GenerateFile() { if (SqlGeneratorSetting == null) { Alert.Error("请先连接数据库"); return; } if (string.IsNullOrWhiteSpace(ComboBox_Database.Text)) { Alert.Error("请先选择数据库并勾选需要生成的表单"); return; } if (CheckedListBox_DataTable.CheckedItems.Count <= 0) { Alert.Error("请先勾选需要生成的表单"); return; } if (string.IsNullOrWhiteSpace(TextBox_SaveLocation.Text) && !ChangeSavePath()) { Alert.Error("请选择生成位置"); return; } if (!Directory.Exists(TextBox_SaveLocation.Text)) { Directory.CreateDirectory(TextBox_SaveLocation.Text); } using (var loadingForm = new WaitForm("正在生成", CheckedListBox_DataTable.CheckedItems.Count)) { var database = ComboBox_Database.Text; var modelSetting = new ModelSetting() { Using = TextBox_Using.Text.Trim(), Namespace = TextBox_NameSpace.Text.Trim(), TabSpace = NumBox_TabSpace.Value.ToInt(), AccessModifier = ComboBox_AccessModifier.Text.Trim(), Inherit = TextBox_Inherit.Text.Trim(), UseSummary = CheckBox_UseSummary.Checked, EnableSQLSugarSupport = ToolStripMenuItem_EnableSQLSugarDefaultSupport.Checked }; var hasGenerateError = false; var thread = new Thread(() => { using (var uniGen = new UniversalGenerator(SqlGeneratorSetting)) { if (!uniGen.TryGetConnection(out var message)) { Alert.Error(message); loadingForm.WorkComplete(); return; } for (int i = 0, showcount = 1; i < CheckedListBox_DataTable.CheckedItems.Count; ++i, ++showcount) { try { var modelName = CheckedListBox_DataTable.CheckedItems[i].ToString(); loadingForm.RefreshState(showcount, $"正在生成:\r\n{modelName}.cs"); modelSetting.ModelName = modelName; modelSetting.ModelSummary = $"Model: {modelName}"; modelSetting.Columns = uniGen.GetColumns(database, modelName); var generated_text = ModelGenerator.Generate(modelSetting); using (var sw = new StreamWriter($"{TextBox_SaveLocation.Text}\\{modelName}.cs")) { sw.Write(generated_text); } } catch (Exception ex) { hasGenerateError = true; var logFilePath = $"{TextBox_SaveLocation.Text}\\error.log"; if (!File.Exists(logFilePath)) { var fs = File.Create(logFilePath); fs.Dispose(); } using (var sw = new StreamWriter(logFilePath, true)) { sw.WriteLine($@"=== Exception log {DateTime.Now:yyyy-MM-dd hh:mm:ss} BEGINS === Exception message: {ex.Message} Exception stack trace: {ex.StackTrace} === Exception log ENDS ==="); } } } } loadingForm.WorkComplete(); }) { IsBackground = true }; loadingForm.StartWork(thread); if (hasGenerateError) { Alert.Warning("生成已完成,但出现错误,错误报告已生成在与实体类相同的目录下"); } else { Alert.Info("生成已完成"); } } }
public void HashCode() { // Verify that GetHashCode() works. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_DataModel).Namespace, }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); using (var context = new AssemblyContext("Neon.ModelGen.Output", assemblyStream)) { // Verify that we see a [InvalidOperationException] when computing a hash // on a data model with no properties tagged by [HashSource]. var emptyData = context.CreateDataWrapper <EmptyData>(); Assert.Throws <InvalidOperationException>(() => emptyData.GetHashCode()); // Verify that we compute HASH=0 for a data model with a // single tagged parameter set to NULL. var baseData = context.CreateDataWrapper <BaseModel>(); Assert.Equal(0, baseData.GetHashCode()); // Verify that we compute a non-zero HASH for a data model with a // single tagged parameter set to to a value. baseData = context.CreateDataWrapper <BaseModel>(); baseData["ParentProperty"] = "Hello World!"; Assert.NotEqual(0, baseData.GetHashCode()); // Verify that we can compute a HASH code for a derived class // and that the hash includes properties from both the derived // and parent classes. var derivedData = context.CreateDataWrapper <DerivedModel>(); derivedData["ChildProperty"] = "Goodbye World!"; var derivedCode1 = derivedData.GetHashCode(); Assert.NotEqual(0, derivedCode1); derivedData["ParentProperty"] = "Hello World!"; var derivedCode2 = derivedData.GetHashCode(); Assert.NotEqual(0, derivedCode2); Assert.NotEqual(derivedCode1, derivedCode2); // Verify that we can compute hash codes for models // with multiple hash source properties. var defaultValues = context.CreateDataWrapper <DefaultValues>(); defaultValues["Name"] = null; defaultValues["Age"] = 0; Assert.Equal(0, defaultValues.GetHashCode()); defaultValues["Name"] = "JoeBob"; defaultValues["Age"] = 0; Assert.Equal("JoeBob".GetHashCode(), defaultValues.GetHashCode()); defaultValues["Name"] = null; defaultValues["Age"] = 67; Assert.Equal(67.GetHashCode(), defaultValues.GetHashCode()); defaultValues["Name"] = "JoeBob"; defaultValues["Age"] = 67; Assert.Equal(67.GetHashCode() ^ "JoeBob".GetHashCode(), defaultValues.GetHashCode()); } }
public void GenerateModelsCheckNames() { var generatorOptions = new GeneratorOptions(); generatorOptions.Model.Read.Generate = true; generatorOptions.Model.Create.Generate = true; generatorOptions.Model.Update.Generate = true; generatorOptions.Model.Validator.Generate = true; generatorOptions.Model.Mapper.Generate = true; var databaseModel = new DatabaseModel { DatabaseName = "TestDatabase", DefaultSchema = "dbo" }; var testTable = new DatabaseTable { Database = databaseModel, Name = "TestTable", Schema = "dbo" }; databaseModel.Tables.Add(testTable); var identifierColumn = new DatabaseColumn { Table = testTable, Name = "Id", IsNullable = false, StoreType = "int" }; testTable.Columns.Add(identifierColumn); var nameColumn = new DatabaseColumn { Table = testTable, Name = "Name", IsNullable = true, StoreType = "varchar(50)" }; testTable.Columns.Add(nameColumn); var generator = new ModelGenerator(NullLoggerFactory.Instance); var typeMappingSource = CreateTypeMappingSource(); var result = generator.Generate(generatorOptions, databaseModel, typeMappingSource); result.ContextClass.Should().Be("TestDatabaseContext"); result.ContextNamespace.Should().Be("TestDatabase.Data"); result.Entities.Count.Should().Be(1); var firstEntity = result.Entities[0]; firstEntity.TableName.Should().Be("TestTable"); firstEntity.TableSchema.Should().Be("dbo"); firstEntity.EntityClass.Should().Be("TestTable"); firstEntity.EntityNamespace.Should().Be("TestDatabase.Data.Entities"); firstEntity.MappingClass.Should().Be("TestTableMap"); firstEntity.MappingNamespace.Should().Be("TestDatabase.Data.Mapping"); firstEntity.MapperClass.Should().Be("TestTableProfile"); firstEntity.MapperNamespace.Should().Be("TestDatabase.Domain.Mapping"); firstEntity.Properties.Count.Should().Be(2); firstEntity.Models.Count.Should().Be(3); var firstModel = firstEntity.Models[0]; firstModel.ModelClass.Should().StartWith("TestTable"); firstModel.ModelClass.Should().EndWith("Model"); firstModel.ModelNamespace.Should().Be("TestDatabase.Domain.Models"); firstModel.ValidatorClass.Should().StartWith("TestTable"); firstModel.ValidatorClass.Should().EndWith("Validator"); firstModel.ValidatorNamespace.Should().Be("TestDatabase.Domain.Validation"); }
public void SerializationDefaults() { // Verify that we honor the [JsonProperty(DefaultValueHandling)] options. var settings = new ModelGeneratorSettings() { SourceNamespace = typeof(Test_DataModel).Namespace, }; var generator = new ModelGenerator(settings); var output = generator.Generate(Assembly.GetExecutingAssembly()); Assert.False(output.HasErrors); var assemblyStream = ModelGenerator.Compile(output.SourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references)); using (var context = new AssemblyContext("Neon.ModelGen.Output", assemblyStream)) { var data = context.CreateDataWrapper <SerializationDefaultsModel>(); // Verify that the instance starts out with the correct // default property values. Assert.Equal("Ignore", data["Ignore"]); Assert.Equal("IgnoreAndPopulate", data["IgnoreAndPopulate"]); Assert.Equal("Include", data["Include"]); Assert.Equal("Populate", data["Populate"]); // Verify that we get the same output when serializing // the same data multple times (this wasn't working // early on). var serialized = data.ToString(); Assert.Equal(serialized, data.ToString()); Assert.Equal(serialized, data.ToString()); // Verify that defaults serialize correctly. Assert.Equal("{\"Include\":\"Include\",\"Populate\":\"Populate\"}", data.ToString()); // Verify that defaults deserialize correctly. data = context.CreateDataWrapper <SerializationDefaultsModel>(); data = context.CreateDataWrapperFrom <SerializationDefaultsModel>(data.ToString()); Assert.Equal("Ignore", data["Ignore"]); Assert.Equal("IgnoreAndPopulate", data["IgnoreAndPopulate"]); Assert.Equal("Include", data["Include"]); Assert.Equal("Populate", data["Populate"]); // Verify that non-default values serialize/desearlize correctly. data = context.CreateDataWrapper <SerializationDefaultsModel>(); data["Ignore"] = "NotIgnore"; data["IgnoreAndPopulate"] = "NotIgnoreAndPopulate"; data["Include"] = "NotInclude"; data["Populate"] = "NotPopulate"; Assert.Equal("{\"Ignore\":\"NotIgnore\",\"IgnoreAndPopulate\":\"NotIgnoreAndPopulate\",\"Include\":\"NotInclude\",\"Populate\":\"NotPopulate\"}", data.ToString()); data = context.CreateDataWrapperFrom <SerializationDefaultsModel>(data.ToString()); Assert.Equal("{\"Ignore\":\"NotIgnore\",\"IgnoreAndPopulate\":\"NotIgnoreAndPopulate\",\"Include\":\"NotInclude\",\"Populate\":\"NotPopulate\"}", data.ToString()); Assert.Equal("NotIgnore", data["Ignore"]); Assert.Equal("NotIgnoreAndPopulate", data["IgnoreAndPopulate"]); Assert.Equal("NotInclude", data["Include"]); Assert.Equal("NotPopulate", data["Populate"]); } }