From 44c7309346275eb99c6750660585a92a380a80dc Mon Sep 17 00:00:00 2001 From: Jonathan Lydall Date: Thu, 19 Sep 2024 11:45:44 +0200 Subject: [PATCH] Improvement: Updated to respect new Stored Procedure stereotypes introduced in version `1.1.1` of the `Intent.Modelers.Domain.StoredProcedures` module. --- .../StoredProcedureStereotypeExtensions.cs | 88 ++++++++++++ .../StoredProcedureFactoryExtension.cs | 2 +- ....EntityFrameworkCore.Repositories.imodspec | 6 +- ...es.EntityFrameworkCore.Repositories.csproj | 4 +- .../CustomRepositoryTemplatePartial.cs | 2 +- ...ustomRepositoryInterfaceTemplatePartial.cs | 2 +- .../Templates/GeneralizedStoredProcedure.cs | 134 ++++++++++++++++++ .../Templates/RepositoryOperationHelper.cs | 13 +- .../Templates/StoredProcedureHelpers.cs | 85 +++++------ .../release-notes.md | 3 +- 10 files changed, 289 insertions(+), 50 deletions(-) create mode 100644 Modules/Intent.Modules.EntityFrameworkCore.Repositories/Api/StoredProcedureStereotypeExtensions.cs create mode 100644 Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/GeneralizedStoredProcedure.cs diff --git a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Api/StoredProcedureStereotypeExtensions.cs b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Api/StoredProcedureStereotypeExtensions.cs new file mode 100644 index 0000000000..755ae3ebdc --- /dev/null +++ b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Api/StoredProcedureStereotypeExtensions.cs @@ -0,0 +1,88 @@ +using System; +using Intent.Metadata.Models; +using Intent.Modelers.Domain.Api; +using Intent.Modules.Common; + +namespace Intent.Modules.EntityFrameworkCore.Repositories.Api +{ + /// + /// This file was created manually since these stereotypes use a function to determine applicability. + /// Stereotypes defined in the "Intent.Modelers.Domain.StoredProcedures" module. + /// + internal static class StoredProcedureStereotypeExtensions + { + public static bool TryGetStoredProcedure(this OperationModel operation, out StoredProcedureStereotype storedProcedureStereotype) + { + var stereotype = operation.GetStereotype(StoredProcedureStereotype.Id); + if (stereotype == null) + { + storedProcedureStereotype = default; + return false; + } + + storedProcedureStereotype = new StoredProcedureStereotype(stereotype); + return true; + } + + public static bool TryGetStoredProcedureParameter(this ParameterModel parameter, + out StoredProcedureParameterStereotype storedProcedureParameterStereotype) + { + var stereotype = parameter.GetStereotype(StoredProcedureParameterStereotype.Id); + if (stereotype == null) + { + storedProcedureParameterStereotype = default; + return false; + } + + storedProcedureParameterStereotype = new StoredProcedureParameterStereotype(stereotype); + return true; + } + } + + internal class StoredProcedureStereotype + { + private readonly IStereotype _stereotype; + + public StoredProcedureStereotype(IStereotype stereotype) + { + _stereotype = stereotype; + } + + public const string Id = "f40ff84c-68ad-405f-bda0-1237dd15fc92"; + + public string GetName() => _stereotype.GetProperty("4e2a3f58-6b6e-43c5-9398-f9c3fde593f6").Value; + } + + internal class StoredProcedureParameterStereotype + { + private readonly IStereotype _stereotype; + + public StoredProcedureParameterStereotype(IStereotype stereotype) + { + _stereotype = stereotype; + } + + public const string Id = "6ac91fd5-206c-49da-b4a2-b6ea2cad11f7"; + + public string GetName() => _stereotype.GetProperty("714a95a6-c3ef-4117-a66c-24876c675cd5").Value; + public StoredProcedureParameterDirection GetDirection() + { + var value = _stereotype.GetProperty("39491728-8327-4b94-b9a2-9851dd4b4a01").Value; + + return value switch + { + "In" => StoredProcedureParameterDirection.In, + "Out" => StoredProcedureParameterDirection.Out, + "Both" => StoredProcedureParameterDirection.Both, + _ => throw new Exception($"Unknown value: {value}") + }; + } + + public string GetSqlStringType() => _stereotype.GetProperty("8ba486d3-853c-42b8-acfb-bafb1e2cdb6e"); + public int? GetSize() => _stereotype.GetProperty("a2df34af-2fb9-49e3-ab6e-caff7a27bf99"); + public int? GetPrecision() => _stereotype.GetProperty("ed35ae5c-a708-457d-a22a-145b3b2f1148"); + public int? GetScale() => _stereotype.GetProperty("38d3c607-ac3b-41ea-86b2-b43fa81e101c"); + } + + internal enum StoredProcedureParameterDirection { In, Out, Both } +} diff --git a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/FactoryExtensions/StoredProcedureFactoryExtension.cs b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/FactoryExtensions/StoredProcedureFactoryExtension.cs index 0954609424..c0eb0d39c5 100644 --- a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/FactoryExtensions/StoredProcedureFactoryExtension.cs +++ b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/FactoryExtensions/StoredProcedureFactoryExtension.cs @@ -106,7 +106,7 @@ protected override void OnAfterTemplateRegistrations(IApplication application) foreach (var (entity, repository) in classRepositories) { - var storedProcedures = repository.GetStoredProcedureModels(); + var storedProcedures = repository.GetGeneralizedStoredProcedures(); if (!storedProcedures.Any()) { continue; diff --git a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Intent.EntityFrameworkCore.Repositories.imodspec b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Intent.EntityFrameworkCore.Repositories.imodspec index fc9d214c03..41a1826210 100644 --- a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Intent.EntityFrameworkCore.Repositories.imodspec +++ b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Intent.EntityFrameworkCore.Repositories.imodspec @@ -1,8 +1,8 @@  Intent.EntityFrameworkCore.Repositories - 4.6.4-pre.2 - [4.2.4-a, 5.0.0-a) + 4.7.0-pre.3 + [4.3.0-a, 5.0.0-a) Generates Repositories for Domain Entities Generates Repositories for Domain Entities Intent Architect @@ -70,7 +70,7 @@ - + diff --git a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Intent.Modules.EntityFrameworkCore.Repositories.csproj b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Intent.Modules.EntityFrameworkCore.Repositories.csproj index 000342c526..95d8c3b273 100644 --- a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Intent.Modules.EntityFrameworkCore.Repositories.csproj +++ b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Intent.Modules.EntityFrameworkCore.Repositories.csproj @@ -3,7 +3,7 @@ net8.0 true - 4.6.4-pre.2 + 4.7.0-pre.3 https://intentarchitect.com true @@ -19,7 +19,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/CustomRepository/CustomRepositoryTemplatePartial.cs b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/CustomRepository/CustomRepositoryTemplatePartial.cs index 995f8d7ccb..52e7e3ebe0 100644 --- a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/CustomRepository/CustomRepositoryTemplatePartial.cs +++ b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/CustomRepository/CustomRepositoryTemplatePartial.cs @@ -54,7 +54,7 @@ public CustomRepositoryTemplate(IOutputTarget outputTarget, RepositoryModel mode } }, 1000); - var storedProcedures = Model.GetStoredProcedureModels(); + var storedProcedures = Model.GetGeneralizedStoredProcedures(); if (!storedProcedures.Any()) { return; diff --git a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/CustomRepositoryInterface/CustomRepositoryInterfaceTemplatePartial.cs b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/CustomRepositoryInterface/CustomRepositoryInterfaceTemplatePartial.cs index 46daee237c..232736db93 100644 --- a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/CustomRepositoryInterface/CustomRepositoryInterfaceTemplatePartial.cs +++ b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/CustomRepositoryInterface/CustomRepositoryInterfaceTemplatePartial.cs @@ -32,7 +32,7 @@ public CustomRepositoryInterfaceTemplate(IOutputTarget outputTarget, RepositoryM RepositoryOperationHelper.ApplyMethods(this, @interface, model); }); - var storedProcedures = Model.GetStoredProcedureModels(); + var storedProcedures = Model.GetGeneralizedStoredProcedures(); if (!storedProcedures.Any()) { return; diff --git a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/GeneralizedStoredProcedure.cs b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/GeneralizedStoredProcedure.cs new file mode 100644 index 0000000000..7df3c11934 --- /dev/null +++ b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/GeneralizedStoredProcedure.cs @@ -0,0 +1,134 @@ +using System.Collections.Generic; +using Intent.EntityFrameworkCore.Repositories.Api; +using Intent.Metadata.Models; +using Intent.Modelers.Domain.Api; +using Intent.Modelers.Domain.Repositories.Api; +using Intent.Modules.Common; +using Intent.Modules.EntityFrameworkCore.Repositories.Api; +using Intent.Modules.Modelers.Domain.StoredProcedures.Api; + +namespace Intent.Modules.EntityFrameworkCore.Repositories.Templates; + +internal static class RepositoryModelExtensions +{ + public static IReadOnlyCollection GetGeneralizedStoredProcedures(this RepositoryModel repositoryModel) + { + var results = new List(); + + foreach (var childElement in repositoryModel.InternalElement.ChildElements) + { + var operationModel = childElement.AsOperationModel(); + if (operationModel != null && operationModel.TryGetStoredProcedure(out var storedProcedure)) + { + results.Add(new GeneralizedStoredProcedure(operationModel, storedProcedure)); + } + + if (childElement.IsStoredProcedureModel()) + { + results.Add(new GeneralizedStoredProcedure(childElement.AsStoredProcedureModel())); + } + } + + return results; + } +} + +internal class GeneralizedStoredProcedure : IElementWrapper, IHasTypeReference, IMetadataModel +{ + public GeneralizedStoredProcedure(OperationModel model, StoredProcedureStereotype storedProcedureStereotype) + { + Name = storedProcedureStereotype.GetName(); + Model = model; + InternalElement = model.InternalElement; + + foreach (var parameterModel in model.Parameters) + { + var parameter = new Parameter + { + Model = parameterModel, + InternalElement = parameterModel.InternalElement + }; + + if (parameterModel.TryGetStoredProcedureParameter(out var storedProcedureParameter)) + { + parameter.StoredProcedureDetails = new ParameterStoredProcedureDetails + { + Name = storedProcedureParameter.GetName(), + Direction = storedProcedureParameter.GetDirection(), + Size = storedProcedureParameter.GetSize(), + Precision = storedProcedureParameter.GetPrecision(), + Scale = storedProcedureParameter.GetScale(), + SqlStringType = storedProcedureParameter.GetSqlStringType() + }; + } + + Parameters.Add(parameter); + } + } + + public GeneralizedStoredProcedure(StoredProcedureModel model) + { + var storedProcedure = model.GetStoredProcedureSettings(); + + Name = storedProcedure.NameInSchema(); + Model = model; + InternalElement = model.InternalElement; + + foreach (var parameterModel in model.Parameters) + { + var storedProcedureParameter = parameterModel.GetStoredProcedureParameterSettings(); + + Parameters.Add(new Parameter + { + Model = parameterModel, + InternalElement = parameterModel.InternalElement, + StoredProcedureDetails = new ParameterStoredProcedureDetails + { + Name = parameterModel.Name, + Direction = !storedProcedureParameter.IsOutputParameter() + ? StoredProcedureParameterDirection.In + : StoredProcedureParameterDirection.Out, + Size = storedProcedureParameter.Size(), + Precision = storedProcedureParameter.Precision(), + Scale = storedProcedureParameter.Scale(), + SqlStringType = storedProcedureParameter.SQLStringType().Value + } + }); + } + } + + /// + /// The name in the schema. + /// + public string Name { get; set; } + + public List Parameters { get; set; } = new(); + public IMetadataModel Model { get; set; } + public IElement InternalElement { get; } + public ITypeReference TypeReference => InternalElement.TypeReference; + public string Id => InternalElement.Id; +} + +internal class Parameter : IElementWrapper, IHasTypeReference, IMetadataModel +{ + public Parameter() { } + + public IMetadataModel Model { get; set; } + public IElement InternalElement { get; set; } + public ITypeReference TypeReference => InternalElement.TypeReference; + public string Id => InternalElement.Id; + public ParameterStoredProcedureDetails StoredProcedureDetails { get; set; } +} + +internal class ParameterStoredProcedureDetails +{ + /// + /// The name in the schema. + /// + public string Name { get; set; } + public StoredProcedureParameterDirection Direction { get; set; } + public int? Size { get; set; } + public int? Precision { get; set; } + public int? Scale { get; set; } + public string SqlStringType { get; set; } +} diff --git a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/RepositoryOperationHelper.cs b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/RepositoryOperationHelper.cs index 2940827b9d..62c76588a9 100644 --- a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/RepositoryOperationHelper.cs +++ b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/RepositoryOperationHelper.cs @@ -5,6 +5,7 @@ using Intent.Modules.Common.CSharp.Templates; using Intent.Modules.Common.Templates; using Intent.Modules.Constants; +using Intent.Modules.EntityFrameworkCore.Repositories.Api; namespace Intent.Modules.EntityFrameworkCore.Repositories.Templates; @@ -14,9 +15,14 @@ public static class RepositoryOperationHelper public static void ApplyMethods(ICSharpFileBuilderTemplate template, CSharpClass @class, RepositoryModel repositoryModel) { template.AddDomainTypeSources(); - + foreach (var operationModel in repositoryModel.Operations) { + if (operationModel.TryGetStoredProcedure(out _)) + { + continue; + } + var isAsync = operationModel.Name.EndsWith("Async") || operationModel.HasStereotype("Asynchronous"); @class.AddMethod(GetReturnType(template, operationModel.ReturnType), operationModel.Name, method => { @@ -48,6 +54,11 @@ public static void ApplyMethods(ICSharpFileBuilderTemplate template, CSharpInter foreach (var operationModel in repositoryModel.Operations) { + if (operationModel.TryGetStoredProcedure(out _)) + { + continue; + } + var isAsync = operationModel.Name.EndsWith("Async") || operationModel.HasStereotype("Asynchronous"); @interface.AddMethod(GetReturnType(template, operationModel.ReturnType), operationModel.Name, method => { diff --git a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/StoredProcedureHelpers.cs b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/StoredProcedureHelpers.cs index ef38566916..bf91a54cc1 100644 --- a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/StoredProcedureHelpers.cs +++ b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/Templates/StoredProcedureHelpers.cs @@ -12,6 +12,7 @@ using Intent.Modules.Common.Templates; using Intent.Modules.Common.Types.Api; using Intent.Modules.Constants; +using Intent.Modules.EntityFrameworkCore.Repositories.Api; using Intent.Modules.EntityFrameworkCore.Repositories.Templates.Repository; using Intent.Modules.EntityFrameworkCore.Settings; using Intent.Modules.EntityFrameworkCore.Templates; @@ -25,7 +26,7 @@ internal static class StoredProcedureHelpers { public static void ApplyInterfaceMethods( TTemplate template, - IReadOnlyCollection storedProcedures) + IReadOnlyCollection storedProcedures) where TTemplate : CSharpTemplateBase, ICSharpFileBuilderTemplate { template.AddDomainTypeSources(); @@ -39,24 +40,24 @@ public static void ApplyInterfaceMethods( foreach (var storedProcedure in storedProcedures) { - @interface.AddMethod(GetReturnType(template, storedProcedure), storedProcedure.Name.ToPascalCase(), method => + @interface.AddMethod(GetReturnType(template, storedProcedure), storedProcedure.InternalElement.Name.ToPascalCase(), method => { - method.RepresentsModel(storedProcedure); + method.RepresentsModel(storedProcedure.Model); method.TryAddXmlDocComments(storedProcedure.InternalElement); foreach (var parameter in storedProcedure.Parameters) { - if (parameter.GetStoredProcedureParameterSettings()?.IsOutputParameter() == true) + if (parameter.StoredProcedureDetails != null && parameter.StoredProcedureDetails.Direction != StoredProcedureParameterDirection.In) { continue; } method.AddParameter(template.GetTypeName(parameter.TypeReference), - parameter.Name.ToLocalVariableName()); + parameter.InternalElement.Name.ToLocalVariableName()); } method.AddOptionalCancellationTokenParameter(); - //method.AddDeconstructedReturnMembers(GetReturnProperties(template, storedProcedure).Select(s => s.Name.ToCamelCase()).ToList()); + //method.AddDeconstructedReturnMembers(GetReturnProperties(template, storedProcedure).Select(s => s.InternalElement.Name.ToCamelCase()).ToList()); }); } }); @@ -64,7 +65,7 @@ public static void ApplyInterfaceMethods( public static void ApplyImplementationMethods( TTemplate template, - IReadOnlyCollection storedProcedures, + IReadOnlyCollection storedProcedures, DbContextInstance dbContextInstance) where TTemplate : CSharpTemplateBase, ICSharpFileBuilderTemplate { @@ -85,15 +86,15 @@ public static void ApplyImplementationMethods( { storedProcedure.Validate(); - @class.AddMethod(GetReturnType(template, storedProcedure), storedProcedure.Name.ToPascalCase(), method => + @class.AddMethod(GetReturnType(template, storedProcedure), storedProcedure.InternalElement.Name.ToPascalCase(), method => { method.RepresentsModel(storedProcedure); var returnTupleProperties = storedProcedure.Parameters - .Where(parameter => parameter.GetStoredProcedureParameterSettings()?.IsOutputParameter() == true) + .Where(parameter => parameter.StoredProcedureDetails?.Direction == StoredProcedureParameterDirection.Out) .Select(parameter => { - var sqlParameter = parameter.Name.ToCamelCase().EnsureSuffixedWith("Parameter"); + var sqlParameter = parameter.InternalElement.Name.ToCamelCase().EnsureSuffixedWith("Parameter"); var typeName = template.GetTypeName(parameter.TypeReference, "{0}"); return $"({typeName}){sqlParameter}.Value"; @@ -119,21 +120,20 @@ public static void ApplyImplementationMethods( foreach (var parameter in storedProcedure.Parameters) { - if (parameter.GetStoredProcedureParameterSettings()?.IsOutputParameter() == true) + if (parameter.StoredProcedureDetails?.Direction == StoredProcedureParameterDirection.Out) { continue; } method.AddParameter(template.GetTypeName(parameter.TypeReference), - parameter.Name.ToLocalVariableName()); + parameter.InternalElement.Name.ToLocalVariableName()); } method.AddOptionalCancellationTokenParameter(); - var nameInSchema = storedProcedure.GetStoredProcedureSettings()?.NameInSchema(); - var spName = !string.IsNullOrWhiteSpace(nameInSchema) - ? nameInSchema - : storedProcedure.Name; + var spName = !string.IsNullOrWhiteSpace(storedProcedure.Name) + ? storedProcedure.Name + : storedProcedure.InternalElement.Name; var provider = template.ExecutionContext.Settings.GetDatabaseSettings().DatabaseProvider().AsEnum(); @@ -152,10 +152,15 @@ public static void ApplyImplementationMethods( foreach (var parameter in storedProcedure.Parameters) { - var isOutputParameter = parameter.GetStoredProcedureParameterSettings()?.IsOutputParameter() == true; + if (parameter.StoredProcedureDetails == null) + { + continue; + } + + var isOutputParameter = parameter.StoredProcedureDetails.Direction == StoredProcedureParameterDirection.Out; var isUserDefinedTableType = parameter.TypeReference.Element.IsDataContractModel(); var output = isOutputParameter ? " OUTPUT" : string.Empty; - var parameterName = parameter.Name.ToLocalVariableName(); + var parameterName = parameter.InternalElement.Name.ToLocalVariableName(); var variableName = isOutputParameter || isUserDefinedTableType || returnsScalar ? parameterName.EnsureSuffixedWith("Parameter") : parameterName; @@ -290,7 +295,7 @@ private static void AddReturnStatement(IReadOnlyList returnTupleProperti private record ComplexReturnTypeImplRecord( CSharpClassMethod Method, - StoredProcedureModel StoredProcedure, + GeneralizedStoredProcedure StoredProcedure, string Sql, ICanBeReferencedType ReturnTypeElement, string ResultVariableName, @@ -305,7 +310,7 @@ public static IReadOnlyCollection GetStoredProcedureModels .ToArray(); } - public static void Validate(this StoredProcedureModel storedProc) + public static void Validate(this GeneralizedStoredProcedure storedProc) { foreach (var parameter in storedProc.Parameters) { @@ -331,7 +336,7 @@ public static void Validate(this StoredProcedureModel storedProc) if (!parameter.TypeReference.IsCollection) { - Logging.Log.Failure($"Parameter \"{parameter.Name}\" [{parameter.Id}] on Stored Procedure \"{storedProc.Name}\" [{storedProc.Id}] " + + Logging.Log.Failure($"Parameter \"{parameter.InternalElement.Name}\" [{parameter.Id}] on Stored Procedure \"{storedProc.InternalElement.Name}\" [{storedProc.Id}] " + $"has \"Is Collection\" disabled and is of type \"Data Contract\", this is " + $"unsupported for user-defined table types."); } @@ -341,7 +346,7 @@ public static void Validate(this StoredProcedureModel storedProc) if (parameter.TypeReference.IsCollection) { - Logging.Log.Failure($"Parameter \"{parameter.Name}\" [{parameter.Id}] on Stored Procedure \"{storedProc.Name}\" [{storedProc.Id}] " + + Logging.Log.Failure($"Parameter \"{parameter.InternalElement.Name}\" [{parameter.Id}] on Stored Procedure \"{storedProc.InternalElement.Name}\" [{storedProc.Id}] " + $"has \"Is Collection\" enabled and is not of type \"Data Contract\", this is " + $"unsupported."); } @@ -350,12 +355,12 @@ public static void Validate(this StoredProcedureModel storedProc) private record TupleEntry(string Name, string TypeName); - private static IReadOnlyList GetReturnProperties(ICSharpTemplate template, StoredProcedureModel storedProcedure) + private static IReadOnlyList GetReturnProperties(ICSharpTemplate template, GeneralizedStoredProcedure storedProcedure) { var tupleProperties = storedProcedure.Parameters - .Where(parameter => parameter.GetStoredProcedureParameterSettings()?.IsOutputParameter() == true) + .Where(parameter => parameter.StoredProcedureDetails?.Direction == StoredProcedureParameterDirection.Out) .Select(parameter => new TupleEntry( - Name: parameter.Name.ToPascalCase().EnsureSuffixedWith("Output"), + Name: parameter.InternalElement.Name.ToPascalCase().EnsureSuffixedWith("Output"), TypeName: template.GetTypeName(parameter.TypeReference) )) .ToList(); @@ -371,7 +376,7 @@ private static IReadOnlyList GetReturnProperties(ICSharpTemplate tem return tupleProperties; } - private static CSharpType GetReturnType(ICSharpTemplate template, StoredProcedureModel storedProcedure) + private static CSharpType GetReturnType(ICSharpTemplate template, GeneralizedStoredProcedure storedProcedure) { var tupleProperties = GetReturnProperties(template, storedProcedure); @@ -387,16 +392,16 @@ private interface IDbParameterFactory { CSharpStatement CreateForOutput(string invocationPrefix, string valueVariableName, - StoredProcedureParameterModel parameter); + Parameter parameter); CSharpStatement CreateForInput( string invocationPrefix, string valueVariableName, - StoredProcedureParameterModel parameter); + Parameter parameter); CSharpStatement CreateForTableType( string invocationPrefix, - StoredProcedureParameterModel parameter); + Parameter parameter); } /// @@ -420,7 +425,7 @@ public SqlDbParameterFactory(ICSharpFileBuilderTemplate template) public CSharpStatement CreateForOutput(string invocationPrefix, string valueVariableName, - StoredProcedureParameterModel parameter) + Parameter parameter) { var statement = new CSharpObjectInitializerBlock($"{invocationPrefix}new {ParameterTypeName}"); @@ -428,7 +433,7 @@ public CSharpStatement CreateForOutput(string invocationPrefix, statement.AddObjectInitStatement("SqlDbType", $"{DbTypeTypeName}.{GetSqlDbType(parameter)}"); if (parameter.TypeReference.HasStringType()) { - var size = parameter.GetStoredProcedureParameterSettings()?.Size(); + var size = parameter.StoredProcedureDetails?.Size; if (size.HasValue) { statement.AddObjectInitStatement("Size", size.ToString()); @@ -436,8 +441,8 @@ public CSharpStatement CreateForOutput(string invocationPrefix, } if (parameter.TypeReference.HasDecimalType()) { - var precision = parameter.GetStoredProcedureParameterSettings()?.Precision(); - var scale = parameter.GetStoredProcedureParameterSettings()?.Scale(); + var precision = parameter.StoredProcedureDetails?.Precision; + var scale = parameter.StoredProcedureDetails?.Scale; if (_template.ExecutionContext.Settings.GetDatabaseSettings().TryGetDecimalPrecisionAndScale(out var constraints)) { precision ??= constraints.Precision; @@ -462,7 +467,7 @@ public CSharpStatement CreateForOutput(string invocationPrefix, public CSharpStatement CreateForInput( string invocationPrefix, string valueVariableName, - StoredProcedureParameterModel parameter) + Parameter parameter) { var statement = new CSharpObjectInitializerBlock($"{invocationPrefix}new {ParameterTypeName}"); @@ -477,7 +482,7 @@ public CSharpStatement CreateForInput( public CSharpStatement CreateForTableType( string invocationPrefix, - StoredProcedureParameterModel parameter) + Parameter parameter) { var dataContractModel = parameter.TypeReference.Element.AsDataContractModel(); var userDefinedTableName = dataContractModel.GetUserDefinedTableTypeSettings()?.Name(); @@ -493,14 +498,14 @@ public CSharpStatement CreateForTableType( statement.AddObjectInitStatement("IsNullable", parameter.TypeReference.IsNullable ? "true" : "false"); statement.AddObjectInitStatement("SqlDbType", $"{DbTypeTypeName}.Structured"); - statement.AddObjectInitStatement("Value", $"{parameter.Name.ToLocalVariableName()}.ToDataTable()"); + statement.AddObjectInitStatement("Value", $"{parameter.InternalElement.Name.ToLocalVariableName()}.ToDataTable()"); statement.AddObjectInitStatement("TypeName", $"\"{userDefinedTableName}\""); statement.WithSemicolon(); return statement; } - private static string GetSqlDbType(StoredProcedureParameterModel parameter) + private static string GetSqlDbType(Parameter parameter) { // https://learn.microsoft.com/dotnet/framework/data/adonet/sql-server-data-type-mappings return parameter.TypeReference.Element.Name.ToLowerInvariant() switch @@ -523,10 +528,10 @@ private static string GetSqlDbType(StoredProcedureParameterModel parameter) }; } - private static string GetStringSqlType(StoredProcedureParameterModel parameter) + private static string GetStringSqlType(Parameter parameter) { - var sqlStringType = parameter.GetStoredProcedureParameterSettings()?.SQLStringType(); - return sqlStringType?.Value switch + var sqlStringType = parameter.StoredProcedureDetails?.SqlStringType; + return sqlStringType switch { null => "VarChar", var value => value diff --git a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/release-notes.md b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/release-notes.md index 30333391ef..b479a78500 100644 --- a/Modules/Intent.Modules.EntityFrameworkCore.Repositories/release-notes.md +++ b/Modules/Intent.Modules.EntityFrameworkCore.Repositories/release-notes.md @@ -1,5 +1,6 @@ -### Version 4.6.4 +### Version 4.7.0 +- Improvement: Updated to respect new Stored Procedure stereotypes introduced in version `1.1.1` of the `Intent.Modelers.Domain.StoredProcedures` module. - Fixed: When domain types (such as a Classes, DataContract and Enums) were used on repository operations, usings would not always be added. - Fixed: Repository Operations now also recognize the `Asynchronous` stereotype.