diff --git a/src/BlueWest.EfMethods/EfMethods/EfAddMethodsAttributeSource.cs b/src/BlueWest.EfMethods/EfMethods/AttributeSources/EfAddMethodsAttributeSource.cs
similarity index 100%
rename from src/BlueWest.EfMethods/EfMethods/EfAddMethodsAttributeSource.cs
rename to src/BlueWest.EfMethods/EfMethods/AttributeSources/EfAddMethodsAttributeSource.cs
diff --git a/src/BlueWest.EfMethods/EfMethods/AttributeSources/EfAddToListAttributeSource.cs b/src/BlueWest.EfMethods/EfMethods/AttributeSources/EfAddToListAttributeSource.cs
new file mode 100644
index 0000000..aac5979
--- /dev/null
+++ b/src/BlueWest.EfMethods/EfMethods/AttributeSources/EfAddToListAttributeSource.cs
@@ -0,0 +1,43 @@
+using BlueWest.EfMethods.Sources;
+using static BlueWest.EfMethods.Sources.Constants;
+
+namespace BlueWest.EfMethods.EfMethods.AttributeSources
+{
+ public static class EfAddToListAttributeSource
+ {
+ internal const string AttributeName = "EfAddToList";
+ internal const string AttributeClassName = AttributeName + "Attribute";
+ internal const string FullyQualifiedName = RootNamespace + "." + AttributeClassName;
+
+ internal static SourceCode Generate(SourceGenerationOptions options)
+ {
+ using var builder = new SourceBuilder()
+ .WriteLine(GeneratedFilesHeader)
+ .WriteLine("using System;")
+ .WriteLine()
+ .WriteLine($"namespace {RootNamespace}")
+ .WriteOpeningBracket();
+
+ builder
+ .WriteLine("/// ")
+ .WriteLine("/// Attribute for generating a function to get many entities.")
+ .WriteLine("/// ");
+
+
+ builder
+ .WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]")
+ .WriteLine($"public sealed class {AttributeName}Attribute : Attribute")
+ .WriteOpeningBracket();
+
+ builder
+ .WriteLine($"public {AttributeName}Attribute(string listPropertyNameof, Type createType, Type returnType, string primaryKeyNameof){"{}"}")
+ .WriteLine();
+
+ builder
+ .WriteClosingBracket() // class
+ .WriteClosingBracket(); // namespace
+
+ return new(builder.ToString(), $"{AttributeName}Attribute.g.cs");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/BlueWest.EfMethods/EfMethods/AttributeSources/EfGetListAttributeSource.cs b/src/BlueWest.EfMethods/EfMethods/AttributeSources/EfGetListAttributeSource.cs
new file mode 100644
index 0000000..3c91a56
--- /dev/null
+++ b/src/BlueWest.EfMethods/EfMethods/AttributeSources/EfGetListAttributeSource.cs
@@ -0,0 +1,44 @@
+using BlueWest.EfMethods;
+using BlueWest.EfMethods.Sources;
+using static BlueWest.EfMethods.Sources.Constants;
+
+namespace BlueWest.Sources
+{
+ public class EfGetListAttributeSource
+ {
+ internal const string AttributeName = "EfGetList";
+ internal const string AttributeClassName = AttributeName + "Attribute";
+ internal const string FullyQualifiedName = RootNamespace + "." + AttributeClassName;
+
+ internal static SourceCode Generate(SourceGenerationOptions options)
+ {
+ using var builder = new SourceBuilder()
+ .WriteLine(GeneratedFilesHeader)
+ .WriteLine("using System;")
+ .WriteLine()
+ .WriteLine($"namespace {RootNamespace}")
+ .WriteOpeningBracket();
+
+ builder
+ .WriteLine("/// ")
+ .WriteLine("/// Attribute for generating a function to get many entities.")
+ .WriteLine("/// ");
+
+
+ builder
+ .WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]")
+ .WriteLine($"public sealed class {AttributeName}Attribute : Attribute")
+ .WriteOpeningBracket();
+
+ builder
+ .WriteLine($"public {AttributeName}Attribute(string listPropertyNameof, Type returnType, string primaryKeyNameof){"{}"}")
+ .WriteLine();
+
+ builder
+ .WriteClosingBracket() // class
+ .WriteClosingBracket(); // namespace
+
+ return new(builder.ToString(), $"{AttributeName}Attribute.g.cs");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/BlueWest.EfMethods/EfMethods/EfGeneratorContext.cs b/src/BlueWest.EfMethods/EfMethods/EfGeneratorContext.cs
index b44f9ed..9153e3c 100644
--- a/src/BlueWest.EfMethods/EfMethods/EfGeneratorContext.cs
+++ b/src/BlueWest.EfMethods/EfMethods/EfGeneratorContext.cs
@@ -4,8 +4,10 @@ using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading;
+using BlueWest.EfMethods.EfMethods.AttributeSources;
using BlueWest.EfMethods.Extensions;
using BlueWest.EfMethods.Sources;
+using BlueWest.Sources;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -113,14 +115,18 @@ namespace BlueWest.EfMethods
return new TypeInfo();
}
- protected TypeInfo? FindFirstTypeInfoOfMemberExpressionSyntax(SemanticModel semanticModel, SyntaxNode attributeSyntax)
+ protected TypeInfo? FindTypeInfoOfMemberExpressionSyntax(SemanticModel semanticModel, SyntaxNode attributeSyntax, int skip = 0)
{
semanticModel ??= Compilation.GetSemanticModel(attributeSyntax.SyntaxTree);
var descendentNodes = attributeSyntax
.DescendantNodes();
// Get the type of the key member id
- var expression = descendentNodes.OfType().FirstOrDefault();
+ var expression = descendentNodes
+ .OfType()
+ .Skip(skip)
+ .FirstOrDefault();
+
if (expression != null)
{
return semanticModel.GetTypeInfo(expression);
@@ -130,10 +136,10 @@ namespace BlueWest.EfMethods
}
- protected string ExtractNameOfMemberName(MemberDeclarationSyntax memberDeclarationSyntax, string attributeName, SemanticModel? semanticModel = null)
+ protected string ExtractNameOfMemberName(MemberDeclarationSyntax memberDeclarationSyntax, string attributeName, SemanticModel? semanticModel = null, int skip = 0)
{
var attributeData = memberDeclarationSyntax.GetAttribute(attributeName);
- var sourceSymbol = ExtractNameOfMemberName(attributeData, semanticModel);
+ var sourceSymbol = ExtractNameOfMemberName(attributeData, semanticModel, skip);
return sourceSymbol;
}
@@ -184,7 +190,7 @@ namespace BlueWest.EfMethods
return sourceTypeExpressionSyntax;
}
- protected string ExtractNameOfMemberName(SyntaxNode? attributeSyntax, SemanticModel semanticModel)
+ protected string ExtractNameOfMemberName(SyntaxNode? attributeSyntax, SemanticModel semanticModel, int skip)
{
if (attributeSyntax is null)
{
@@ -195,6 +201,7 @@ namespace BlueWest.EfMethods
.DescendantNodes();
var idNode = descendentNodes.OfType()
+ .Skip(skip)
.FirstOrDefault()
?.ChildNodesAndTokens()
.FirstOrDefault(x => x.IsKind(SyntaxKind.ArgumentList))
@@ -262,17 +269,19 @@ namespace BlueWest.EfMethods
// handles different attributes
- var addAttributeSymbols = GetAllowedMemberSyntaxes(EfAddMethodsAttributeSource.AttributeName);
- var updateAttributesMembers = GetAllowedMemberSyntaxes(EfUpdateMethodsAttributeSource.AttributeName);
- var getOneAttributesMembers = GetAllowedMemberSyntaxes(EfGetOneByAttributeSource.AttributeName);
- var getOneWithAttributesMembers = GetAllowedMemberSyntaxes(EfGetOneAttributeSource.AttributeName);
- var getManyWithAttributesMembers = GetAllowedMemberSyntaxes(EfGetManyAttributeSource.AttributeName);
-
+ var addMembers = GetAllowedMemberSyntaxes(EfAddMethodsAttributeSource.AttributeName);
+ var updateMembers = GetAllowedMemberSyntaxes(EfUpdateMethodsAttributeSource.AttributeName);
+ var getOneByMembers = GetAllowedMemberSyntaxes(EfGetOneByAttributeSource.AttributeName);
+ var getOneMembers = GetAllowedMemberSyntaxes(EfGetOneAttributeSource.AttributeName);
+ var efGetManyMembers = GetAllowedMemberSyntaxes(EfGetManyAttributeSource.AttributeName);
+ var getListMembers = GetAllowedMemberSyntaxes(EfGetListAttributeSource.AttributeName);
+ var getAddToListMembers = GetAllowedMemberSyntaxes(EfAddToListAttributeSource.AttributeName);
+
List methodsModels = new List();
- foreach (var uProperty in getOneAttributesMembers)
+ foreach (var uProperty in getOneByMembers)
{
var entityDataModel = GetEntityData(uProperty, semanticModel);
var newUpdateModel = ExtractEfGetEntityByModel(uProperty, semanticModel, entityDataModel);
@@ -280,14 +289,14 @@ namespace BlueWest.EfMethods
}
- foreach (var uProperty in addAttributeSymbols)
+ foreach (var uProperty in addMembers)
{
var entityDataModel = GetEntityData(uProperty, semanticModel);
var newAddModel = ExtractEfAddMethodsModel(semanticModel, uProperty, entityDataModel);
methodsModels.Add(newAddModel);
}
- foreach (var uProperty in updateAttributesMembers)
+ foreach (var uProperty in updateMembers)
{
var entityDataModel = GetEntityData(uProperty, semanticModel);
var newUpdateModel = ExtractEfUpdateMethodsModel(uProperty, semanticModel, entityDataModel);
@@ -295,7 +304,7 @@ namespace BlueWest.EfMethods
}
- foreach (var uProperty in getOneWithAttributesMembers)
+ foreach (var uProperty in getOneMembers)
{
var entityDataModel = GetEntityData(uProperty, semanticModel);
var newUpdateModel = ExtractEfGetEntityWithModel(uProperty, semanticModel, entityDataModel);
@@ -303,12 +312,29 @@ namespace BlueWest.EfMethods
}
- foreach (var uProperty in getManyWithAttributesMembers)
+ foreach (var uProperty in efGetManyMembers)
{
var entityDataModel = GetEntityData(uProperty, semanticModel);
var newUpdateModel = ExtractEfGetManyModel(uProperty, semanticModel, entityDataModel);
methodsModels.Add(newUpdateModel);
}
+
+ foreach (var uProperty in getListMembers)
+ {
+ var entityDataModel = GetEntityData(uProperty, semanticModel);
+ var newModel = ExtractEfGetListModel(uProperty, semanticModel, entityDataModel);
+ methodsModels.Add(newModel);
+ }
+
+
+ foreach (var uProperty in getAddToListMembers)
+ {
+ var entityDataModel = GetEntityData(uProperty, semanticModel);
+ var newModel = ExtractEfAddToListMethodsModel(uProperty, semanticModel, entityDataModel);
+ methodsModels.Add(newModel);
+ }
+
+
//SpinWait.SpinUntil(() => Debugger.IsAttached);
@@ -364,7 +390,7 @@ namespace BlueWest.EfMethods
GetEntityTypeSymbol(uProperty, EfUpdateMethodsAttributeSource.AttributeName, semanticModel);
var keyPropertyName = ExtractNameOfMemberName(uProperty, EfUpdateMethodsAttributeSource.AttributeName, semanticModel);
- var keyMemberType = FindFirstTypeInfoOfMemberExpressionSyntax(semanticModel, TypeSyntax);
+ var keyMemberType = FindTypeInfoOfMemberExpressionSyntax(semanticModel, TypeSyntax);
//var secondTypeInfo = FindSecondTypeInfoOfMemberExpressionSyntax(semanticModel, TypeSyntax);
var keyMemberFullName = keyMemberType.Value.Type.ToDisplayString();
@@ -453,7 +479,7 @@ namespace BlueWest.EfMethods
var efTypeofSymbols = GetEntityTypeSymbol(uProperty, EfGetOneByAttributeSource.AttributeName, semanticModel);
var byParamPropertyName = ExtractNameOfMemberName(uProperty, EfGetOneByAttributeSource.AttributeName, semanticModel);
- var keyMemberType = FindFirstTypeInfoOfMemberExpressionSyntax(semanticModel, TypeSyntax);
+ var keyMemberType = FindTypeInfoOfMemberExpressionSyntax(semanticModel, TypeSyntax);
var byParamFullTypeName = keyMemberType.Value.Type.ToDisplayString();
@@ -482,6 +508,99 @@ namespace BlueWest.EfMethods
return new EfGetOneByModel(entityDataModel, byParamPropertyName, byParamFullTypeName, returnTypeFullName, returnTypeIdentifierName);
}
+
+ private EfGetListModel ExtractEfGetListModel(MemberDeclarationSyntax uProperty, SemanticModel semanticModel, EfEntityDataModel entityDataModel)
+ {
+
+ var efTypeofSymbols = GetEntityTypeSymbol(uProperty, EfGetListAttributeSource.AttributeName, semanticModel);
+
+ var listPropertyName = ExtractNameOfMemberName(uProperty, EfGetListAttributeSource.AttributeName, semanticModel);
+ var keyPropertyName = ExtractNameOfMemberName(uProperty, EfGetListAttributeSource.AttributeName, semanticModel, 1);;
+ var keyMemberType = FindTypeInfoOfMemberExpressionSyntax(semanticModel, TypeSyntax);
+ var keyFullTypeName = keyMemberType.Value.Type.ToDisplayString();
+
+
+ // Try grabbing string literal if there's no nameof in it
+ if (keyPropertyName == string.Empty)
+ {
+ listPropertyName = GetEntityStringLiteralSymbol(TypeSyntax, EfGetListAttributeSource.AttributeName, semanticModel)
+ .FirstOrDefault()?
+ .Token.ValueText ?? "Id";
+ }
+
+
+ string returnTypeIdentifierName = entityDataModel.EntityTypeIdentifierName;
+ string returnTypeFullName = entityDataModel.EntityTypeFullName;
+
+
+ // Grab return type from attribute argument
+ if (efTypeofSymbols.Length > 0)
+ {
+ returnTypeIdentifierName = efTypeofSymbols[0].Name;
+ returnTypeFullName = efTypeofSymbols[0].ToDisplayString();
+ }
+
+ return new EfGetListModel(entityDataModel, listPropertyName, keyPropertyName, keyFullTypeName, returnTypeIdentifierName, returnTypeFullName);
+ }
+
+ private EfAddToListModel ExtractEfAddToListMethodsModel(MemberDeclarationSyntax uProperty, SemanticModel semanticModel, EfEntityDataModel entityDataModel)
+ {
+
+ //SpinWait.SpinUntil(() => Debugger.IsAttached);
+
+ var efTypeofSymbols = GetEntityTypeSymbol(uProperty, EfAddToListAttributeSource.AttributeName, semanticModel);
+
+ var listPropertyName = ExtractNameOfMemberName(uProperty, EfAddToListAttributeSource.AttributeName, semanticModel);
+ var keyPropertyName = ExtractNameOfMemberName(uProperty, EfAddToListAttributeSource.AttributeName, semanticModel, 1);;
+ var keyMemberType = FindTypeInfoOfMemberExpressionSyntax(semanticModel, TypeSyntax);
+ var keyFullTypeName = keyMemberType.Value.Type.ToDisplayString();
+ var listEntityTypeInfo = (FindTypeInfoOfMemberExpressionSyntax(semanticModel, TypeSyntax, 2).Value.Type as INamedTypeSymbol).TypeArguments.FirstOrDefault();
+ var listEntityIdentifierName = listEntityTypeInfo.Name;
+ var listEntityFullTypeName = listEntityTypeInfo.ToDisplayString();
+
+
+ // Try grabbing string literal if there's no nameof in it
+ if (keyPropertyName == string.Empty)
+ {
+ listPropertyName = GetEntityStringLiteralSymbol(TypeSyntax, EfAddToListAttributeSource.AttributeName, semanticModel)
+ .FirstOrDefault()?
+ .Token.ValueText ?? "Id";
+ }
+
+
+ string returnTypeIdentifierName = entityDataModel.EntityTypeIdentifierName;
+ string returnTypeFullName = entityDataModel.EntityTypeFullName;
+
+ var createTypeIdentifierName =listEntityIdentifierName;
+ var createTypeFullName = listEntityFullTypeName;
+
+ // Grab create type from attribute argument
+ if (efTypeofSymbols.Length > 0)
+ {
+ createTypeIdentifierName = efTypeofSymbols[0].Name;
+ createTypeFullName = efTypeofSymbols[0].ToDisplayString();
+ }
+
+ // Grab return type from attribute argument
+ if (efTypeofSymbols.Length > 1)
+ {
+ returnTypeIdentifierName = efTypeofSymbols[1].Name;
+ returnTypeFullName = efTypeofSymbols[1].ToDisplayString();
+ }
+
+ return new EfAddToListModel(
+ entityDataModel,
+ listPropertyName,
+ listEntityIdentifierName,
+ listEntityFullTypeName,
+ keyPropertyName,
+ keyFullTypeName,
+ createTypeIdentifierName,
+ createTypeFullName,
+ returnTypeIdentifierName,
+ returnTypeFullName);
+ }
+
private static ITypeSymbol GetEntityTypeData(MemberDeclarationSyntax memberDeclarationSyntax, SemanticModel? semanticModel = null)
{
diff --git a/src/BlueWest.EfMethods/EfMethods/EfMethodsGenerator.cs b/src/BlueWest.EfMethods/EfMethods/EfMethodsGenerator.cs
index 73f48e9..894c5c2 100644
--- a/src/BlueWest.EfMethods/EfMethods/EfMethodsGenerator.cs
+++ b/src/BlueWest.EfMethods/EfMethods/EfMethodsGenerator.cs
@@ -3,8 +3,10 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
+using BlueWest.EfMethods.EfMethods.AttributeSources;
using BlueWest.EfMethods.Extensions;
using BlueWest.EfMethods.Sources;
+using BlueWest.Sources;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -35,7 +37,11 @@ namespace BlueWest.EfMethods
.AddSource(ref context, EfUpdateMethodsAttributeSource.Generate(options))
.AddSource(ref context, EfGetOneByAttributeSource.Generate(options))
.AddSource(ref context, EfGetOneAttributeSource.Generate(options))
- .AddSource(ref context, EfGetManyAttributeSource.Generate(options));
+ .AddSource(ref context, EfGetManyAttributeSource.Generate(options))
+ .AddSource(ref context, EfGetListAttributeSource.Generate(options))
+ .AddSource(ref context, EfAddToListAttributeSource.Generate(options));
+
+
if (context.SyntaxReceiver is EfMethodsSyntaxReceiver receiver && receiver.CandidateTypes.Any())
@@ -50,15 +56,29 @@ namespace BlueWest.EfMethods
}
}
+ private static EfTemplates GetAvailableTemplates(GeneratorExecutionContext context)
+ {
+ string addSourceTemplate = GetCsxMethodTemplate(context, "AddToTemplate");
+ string updateSourceTemplate = GetCsxMethodTemplate(context, "UpdateTemplate");
+ string getOneByTemplate = GetCsxMethodTemplate(context, "GetOneByTemplate");
+ string getOneTemplate = GetCsxMethodTemplate(context, "GetOneTemplate");
+ string getManyWithTemplate = GetCsxMethodTemplate(context, "GetManyTemplate");
+ string getListTemplate = GetCsxMethodTemplate(context, "GetListTemplate");
+ string addToListTemplate = GetCsxMethodTemplate(context, "AddToListTemplate");
+
+ return new EfTemplates(
+ addSourceTemplate,
+ updateSourceTemplate,
+ getOneByTemplate,
+ getOneTemplate,
+ getManyWithTemplate,
+ getListTemplate,
+ addToListTemplate);
+ }
+
private static void AddGeneratedExtensions(GeneratorExecutionContext context, Compilation compilation, IEnumerable candidateMembers, SourceGenerationOptions options)
{
- string addSourceTemplate = GetCsxMethodTemplate(context, "AddToEntityTemplate");
- string updateSourceTemplate = GetCsxMethodTemplate(context, "UpdateEntityTemplate");
- string getOneByTemplate = GetCsxMethodTemplate(context, "GetOneByTemplate");
- string getOneWithByTemplate = GetCsxMethodTemplate(context, "GetOneTemplate");
- string getManyWithTemplate = GetCsxMethodTemplate(context, "GetManyTemplate");
-
-
+ var templates = GetAvailableTemplates(context);
foreach (var candidateMember in candidateMembers)
{
@@ -76,11 +96,7 @@ namespace BlueWest.EfMethods
{
ClassDeclarationSyntax => EfMethodsSource.Generate(
mappingContext.Model,
- addSourceTemplate,
- updateSourceTemplate,
- getOneByTemplate,
- getOneWithByTemplate,
- getManyWithTemplate),
+ templates),
_ => throw new ArgumentOutOfRangeException()
};
diff --git a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource.cs b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource.cs
index 9f9a2e4..b054919 100644
--- a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource.cs
+++ b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource.cs
@@ -11,19 +11,10 @@ namespace BlueWest.EfMethods.Sources
{
internal static class EfMethodsSource
{
- internal static SourceCode Generate(EfMethodsModel model,
- string addSourceTemplate,
- string updateSourceTemplate,
- string getOneBySourceTemplate,
- string getOneWithSourceTemplate,
- string getManyWithSourceTemplate
- )
+ internal static SourceCode Generate(EfMethodsModel model, EfTemplates templates)
{
using var builder = new SourceBuilder();
-
-
- var contextFullName = model.ContextFullType;
-
+
builder
.WriteLine(GeneratedFilesHeader)
.WriteUsings(model.Usings)
@@ -31,7 +22,6 @@ namespace BlueWest.EfMethods.Sources
.WriteLine("using System.Linq;")
.WriteLine("using System.Linq.Expressions;")
.WriteLine("using System.Threading.Tasks;")
-
.WriteLine()
// Namespace declaration
.WriteLine($"namespace {model.Namespace}")
@@ -41,46 +31,53 @@ namespace BlueWest.EfMethods.Sources
.WriteOpeningBracket()
.WriteLine();
-
foreach (var methodModel in model.MethodsModels.OrderBy(x => x.PropertyName))
{
switch (methodModel)
{
- case EfAddMethodsModel modl:
+ case EfAddMethodsModel currentModel:
builder
- .EfAddAddEntityMethod(model, modl, addSourceTemplate)
+ .EfAddAddMethod(model, currentModel, templates.AddTemplate)
+ .WriteLine();
+ break;
+
+ case EfUpdateMethodsModel currentModel:
+ builder
+ .EfAddUpdateMethod(model, currentModel, templates.UpdateTemplate)
+ .WriteLine();
+ break;
+
+ case EfGetOneByModel currentModel:
+ builder
+ .EfAddGetOneEntityByMethod(model, currentModel, templates.GetOneByTemplate)
+ .WriteLine();
+ break;
+
+ case EfGetManyModel currentModel:
+ builder
+ .EfAddGetManyMethod(model, currentModel, templates.GetManyTemplate)
+ .WriteLine();
+ break;
+
+ case EfGetOneWithModel currentModel:
+ builder
+ .EfAddGetOneMethod(model, currentModel, templates.GetOneTemplate)
+ .WriteLine();
+ break;
+ case EfGetListModel currentModel:
+ builder
+ .EfAddGetListMethod(model, currentModel, templates.GetListTemplate)
+ .WriteLine();
+ break;
+ case EfAddToListModel currentModel:
+ builder
+ .EfAddAddToListMethod(model, currentModel, templates.AddToListTemplate)
.WriteLine();
break;
- case EfUpdateMethodsModel modl:
- builder
- .EfAddUpdateEntityMethod(model, modl, updateSourceTemplate)
- .WriteLine();
- break;
-
- case EfGetOneByModel modl:
- builder
- .EfAddGetOneEntityByMethod(model, modl, getOneBySourceTemplate)
- .WriteLine();
- break;
- case EfGetManyModel modl:
- builder
- .EfAddGetManyWithMethod(model, modl, getManyWithSourceTemplate)
- .WriteLine();
- break;
- case EfGetOneWithModel modl:
- builder
- .EfAddGetOneEntityWithMethod(model, modl, getOneWithSourceTemplate)
- .WriteLine();
- break;
-
-
-
}
-
-
}
-
+
builder
// End class declaration
.WriteClosingBracket()
@@ -105,9 +102,5 @@ namespace BlueWest.EfMethods.Sources
return builder;
}
-
-
-
-
}
}
\ No newline at end of file
diff --git a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfAddEntityTemplateSource.cs b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfAddEntityTemplateSource.cs
index ce22977..19acc91 100644
--- a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfAddEntityTemplateSource.cs
+++ b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfAddEntityTemplateSource.cs
@@ -1,13 +1,12 @@
using BlueWest.EfMethods.Extensions;
-using System;
-using System.Collections.Generic;
using System.Text;
+using BlueWest.EfMethods.Sources;
-namespace BlueWest.EfMethods.Sources
+namespace BlueWest.EfMethods
{
internal static class EfAddEntityTemplateSource
{
- internal static SourceBuilder EfAddAddEntityMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfAddMethodsModel model, string addSourceTemplate)
+ internal static SourceBuilder EfAddAddMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfAddMethodsModel model, string addSourceTemplate)
{
var returnTypeFullName = model.ReturnTypeFullName;
var createTypeFullName = model.CreateTypeFullName;
diff --git a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfAddToListTemplateSource.cs b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfAddToListTemplateSource.cs
new file mode 100644
index 0000000..8bb68ff
--- /dev/null
+++ b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfAddToListTemplateSource.cs
@@ -0,0 +1,78 @@
+using System.Text;
+using BlueWest.EfMethods.Extensions;
+using BlueWest.EfMethods.Sources;
+
+namespace BlueWest.EfMethods
+{
+ internal static class EfAddToListTemplateSource
+ {
+ internal static SourceBuilder EfAddAddToListMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfAddToListModel model, string template)
+ {
+ var returnTypeFullName = model.ReturnTypeFullName;
+ var entityTypeName = model.EntityTypeIdentifierName;
+ var listPropertyName = model.ListPropertyName;
+ var listEntityCreateFullName = model.CreateTypeFullName;
+ var listItemCreateVarName = model.ListEntityIdentifierName.ToCamelCase() + "toCreate";
+ var listEntityTypeName = model.ListEntityIdentifierName;
+ var listEntityFullName = model.ListEntityFullTypeName;
+
+ var contextFullName = methodsModel.ContextFullType;
+ var propertyName = model.PropertyName;
+ var primaryKeyFullName = model.KeyFullTypeName;
+ var primaryKeyPropertyName = model.KeyPropertyName;
+ var primaryKeyVarName = model.KeyPropertyName.ToCamelCase();
+ var entityObjectVarName = model.EntityTypeIdentifierName.ToCamelCase();
+
+
+ if (!template.IsEmpty())
+ {
+ var templateToSourceBuilder = new StringBuilder(template);
+ templateToSourceBuilder
+ .Replace("{returnTypeFullName}", returnTypeFullName)
+ .Replace("{entityTypeName}", entityTypeName)
+ .Replace("{contextFullName}", contextFullName)
+ .Replace("{listPropertyName}", listPropertyName)
+ .Replace("{primaryKeyPropertyName}", primaryKeyPropertyName)
+ .Replace("{primaryKeyFullName}", primaryKeyFullName)
+ .Replace("{primaryKeyVarName}", primaryKeyVarName)
+ .Replace("{entityObjectVarName}", entityObjectVarName)
+ .Replace("{propertyName}", propertyName)
+ .Replace("{listEntityCreateFullName}", listEntityCreateFullName)
+ .Replace("{listEntityTypeName}", listEntityTypeName)
+ .Replace("{listEntityFullName}", listEntityFullName)
+ .Replace("{listItemCreateVarName}", listItemCreateVarName)
+ .Replace("{primaryKeyPropertyName}", primaryKeyPropertyName);
+
+
+ builder
+ .ParseTemplate(templateToSourceBuilder.ToString());
+ }
+
+ if (template.IsEmpty())
+ {
+ builder
+ .WriteComment("Generated body")
+ //.WriteLine(GeneratedFilesHeader)
+ .WriteLine($"public static (bool, string, {returnTypeFullName}) Add{listEntityTypeName}To{entityTypeName}( this {contextFullName} dbContext, {primaryKeyFullName} {primaryKeyVarName}, {listEntityCreateFullName} {listItemCreateVarName})")
+ .WriteOpeningBracket()
+ .WriteLine($"var entityQuery = from aEntity in dbContext.{propertyName}")
+ .WriteLine($"where aEntity.{primaryKeyVarName} == {primaryKeyVarName}")
+ .WriteLine($"let itemsInList = aEntity.{listPropertyName}")
+ .WriteLine($"select aEntity;")
+ .WriteLine()
+ .WriteLine($"var entity = entityQuery.FirstOrDefault();")
+ .WriteLine($"if (entity == null) return (false, $\"{entityTypeName} not found.\", null);")
+ .WriteLine($"var newListItem = new {listEntityFullName}({listItemCreateVarName});")
+ .WriteLine($"entity.{listPropertyName}.Add({listItemCreateVarName});")
+ .WriteLine($"var success = dbContext.SaveChanges() >= 0;")
+ .WriteLine($"return !success ? (false, \"Error saving changes in the Database. Action: Create {listEntityTypeName} in {entityTypeName}.\", null) : (true, string.Empty, new {returnTypeFullName}(newListItem));")
+ .WriteClosingBracket();
+
+ builder
+ .WriteLine();
+ }
+
+ return builder;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfGetListTemplateSource.cs b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfGetListTemplateSource.cs
new file mode 100644
index 0000000..012a889
--- /dev/null
+++ b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfGetListTemplateSource.cs
@@ -0,0 +1,68 @@
+using System.Text;
+using BlueWest.EfMethods.Extensions;
+using BlueWest.EfMethods.Sources;
+
+namespace BlueWest.EfMethods
+{
+ public static class EfGetListTemplateSource
+ {
+ internal static SourceBuilder EfAddGetListMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfGetListModel model, string addSourceTemplate)
+ {
+ var returnTypeFullName = model.ReturnTypeFullName;
+ var entityTypeName = model.EntityTypeIdentifierName;
+ var listPropertyName = model.ListPropertyName;
+ var contextFullName = methodsModel.ContextFullType;
+ var propertyName = model.PropertyName;
+ var primaryKeyFullName = model.KeyFullTypeName;
+ var primaryKeyPropertyName = model.KeyPropertyName;
+ var primaryKeyVarName = model.KeyPropertyName.ToCamelCase();
+ var entityObjectVarName = model.EntityTypeIdentifierName.ToCamelCase();
+
+ if (!addSourceTemplate.IsEmpty())
+ {
+ var templateToSourceBuilder = new StringBuilder(addSourceTemplate);
+ templateToSourceBuilder
+ .Replace("{returnTypeFullName}", returnTypeFullName)
+ .Replace("{entityTypeName}", entityTypeName)
+ .Replace("{contextFullName}", contextFullName)
+ .Replace("{listPropertyName}", listPropertyName)
+ .Replace("{primaryKeyPropertyName}", primaryKeyPropertyName)
+ .Replace("{primaryKeyFullName}", primaryKeyFullName)
+ .Replace("{primaryKeyVarName}", primaryKeyVarName)
+ .Replace("{entityObjectVarName}", entityObjectVarName)
+ .Replace("{propertyName}", propertyName);
+
+ builder
+ .ParseTemplate(templateToSourceBuilder.ToString());
+ }
+
+ if (addSourceTemplate.IsEmpty())
+ {
+ builder
+ .WriteComment("Generated body")
+ //.WriteLine(GeneratedFilesHeader)
+ .WriteLine($"public static (bool, {returnTypeFullName}[]) Get{entityTypeName}{listPropertyName}(this {contextFullName} dbContext, {primaryKeyFullName} {primaryKeyVarName},")
+ .WriteLine($"int skip = 0, int take = 50, int orderDir = 1, Expression> orderBy = null)")
+ .WriteOpeningBracket()
+ .WriteLine($"var {entityObjectVarName} = dbContext.{propertyName}.FirstOrDefault(d => d.{primaryKeyPropertyName} == {primaryKeyVarName});")
+ .WriteLine($"if ({entityObjectVarName} == null) return (false, null);")
+ .WriteLine($"var currentTake = take;")
+ .WriteLine($"if (take > 200) currentTake = 200;")
+ .WriteLine($"var query = dbContext")
+ .WriteLine($".{propertyName}")
+ .WriteLine($".Where(data => data.{primaryKeyPropertyName} == {primaryKeyVarName})")
+ .WriteLine($".SelectMany(o => o.{listPropertyName})")
+ .WriteLine($".Select(x => new {returnTypeFullName}(x))")
+ .WriteLine($".Skip(skip)")
+ .WriteLine($"if(orderBy != null) query = orderDir == 1 ? query.OrderBy(orderBy) : query.OrderByDescending(orderBy);")
+ .WriteLine($"return (query.Any(), query.ToArray());")
+ .WriteClosingBracket();
+
+ builder
+ .WriteLine();
+ }
+
+ return builder;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfGetOneEntityByTemplate.cs b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfGetOneEntityByTemplate.cs
index 794be4a..4d6c5ed 100644
--- a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfGetOneEntityByTemplate.cs
+++ b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfGetOneEntityByTemplate.cs
@@ -28,7 +28,6 @@ namespace BlueWest.EfMethods
.Replace("{entityTypeName}", entityTypeName)
.Replace("{byParamPropertyName}", byParamPropertyName)
.Replace("{contextFullName}", contextFullName)
- .Replace("{contextFullName}", contextFullName)
.Replace("{byParamFullType}", byParamFullType)
.Replace("{byParamVarName}", byParamVarName)
diff --git a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfGetOneWithTemplateSource.cs b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfGetOneWithTemplateSource.cs
index b1551cb..3d57575 100644
--- a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfGetOneWithTemplateSource.cs
+++ b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfGetOneWithTemplateSource.cs
@@ -8,7 +8,7 @@ namespace BlueWest.EfMethods
{
internal static class EfGetOneWithTemplateSource
{
- internal static SourceBuilder EfAddGetOneEntityWithMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfGetOneWithModel model, string addSourceTemplate)
+ internal static SourceBuilder EfAddGetOneMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfGetOneWithModel model, string addSourceTemplate)
{
var returnTypeFullName = model.ReturnTypeFullName;
var entityTypeName = model.EntityTypeIdentifierName;
@@ -53,7 +53,7 @@ namespace BlueWest.EfMethods
return builder;
}
- internal static SourceBuilder EfAddGetManyWithMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfGetManyModel model, string addSourceTemplate)
+ internal static SourceBuilder EfAddGetManyMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfGetManyModel model, string addSourceTemplate)
{
var returnTypeFullName = model.ReturnTypeFullName;
var entityTypeName = model.EntityTypeIdentifierName;
diff --git a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfUpdateEntityTemplateSource.cs b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfUpdateEntityTemplateSource.cs
index 634cb35..1be2132 100644
--- a/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfUpdateEntityTemplateSource.cs
+++ b/src/BlueWest.EfMethods/EfMethods/EfMethodsSource/EfUpdateEntityTemplateSource.cs
@@ -7,7 +7,7 @@ namespace BlueWest.EfMethods.Sources
{
internal static class EfUpdateEntityTemplateSource
{
- internal static SourceBuilder EfAddUpdateEntityMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfUpdateMethodsModel model, string updateSourceTemplate)
+ internal static SourceBuilder EfAddUpdateMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfUpdateMethodsModel model, string updateSourceTemplate)
{
var entityTypeName = model.EntityTypeIdentifierName;
var contextFullName = methodsModel.ContextFullType;
diff --git a/src/BlueWest.EfMethods/Models.cs b/src/BlueWest.EfMethods/Models.cs
index fbc772e..be2687f 100644
--- a/src/BlueWest.EfMethods/Models.cs
+++ b/src/BlueWest.EfMethods/Models.cs
@@ -32,6 +32,17 @@ namespace BlueWest.EfMethods
ImmutableArray Usings
);
+
+ record EfTemplates(
+ string AddTemplate,
+ string UpdateTemplate,
+ string GetOneByTemplate,
+ string GetOneTemplate,
+ string GetManyTemplate,
+ string GetListTemplate,
+ string AddToListTemplate
+ );
+
internal class EfEntityDataModel
{
public string PropertyName { get; set; }
@@ -90,8 +101,8 @@ namespace BlueWest.EfMethods
internal class EfGetOneWithModel : EfEntityDataModel
{
- public string ReturnTypeIdentifierName { get; set; }
- public string ReturnTypeFullName { get; set; }
+ public string ReturnTypeIdentifierName { get; }
+ public string ReturnTypeFullName { get; }
public EfGetOneWithModel(EfEntityDataModel entity, string returnTypeFullName,
string returnTypeIdentifierName) : base(entity.PropertyName, entity.EntityTypeFullName, entity.EntityTypeIdentifierName)
@@ -119,10 +130,10 @@ namespace BlueWest.EfMethods
{
public string UpdateTypeFullName;
public string UpdateTypeIdentifierName;
- public string ReturnTypeFullName;
+ public readonly string ReturnTypeFullName;
public string ReturnTypeIdentifierName;
- public string KeyPropertyName;
- public string KeyFullTypeName;
+ public readonly string KeyPropertyName;
+ public readonly string KeyFullTypeName;
public EfUpdateMethodsModel(EfEntityDataModel entity,
string updateTypeFullName,
string updateTypeIdentifierName,
@@ -139,6 +150,80 @@ namespace BlueWest.EfMethods
KeyFullTypeName = keyFullTypeName;
}
}
+
+
+ internal class EfGetListModel : EfEntityDataModel
+ {
+ public string ListPropertyName { get; set; }
+ public string KeyPropertyName { get; set; }
+ public string KeyFullTypeName { get; set; }
+ public string ReturnTypeIdentifierName { get; set; }
+ public string ReturnTypeFullName { get; set; }
+
+
+ public EfGetListModel(
+ EfEntityDataModel entity,
+ string listPropertyName,
+ string keyPropertyName,
+ string keyFullTypeName,
+ string returnTypeIdentifierName,
+ string returnTypeFullName)
+ : base(entity.PropertyName, entity.EntityTypeFullName, entity.EntityTypeIdentifierName)
+ {
+ ListPropertyName = listPropertyName;
+ KeyPropertyName = keyPropertyName;
+ KeyFullTypeName = keyFullTypeName;
+ ReturnTypeIdentifierName = returnTypeIdentifierName;
+ ReturnTypeFullName = returnTypeFullName;
+ }
+ }
+
+
+ internal class EfAddToListModel : EfEntityDataModel
+ {
+ public string ListPropertyName { get; set; }
+
+ public string ListEntityIdentifierName { get; set; }
+ public string ListEntityFullTypeName { get; set; }
+
+ public string KeyPropertyName { get; set; }
+ public string KeyFullTypeName { get; set; }
+
+ public string CreateTypeIdentifierName { get; set; }
+ public string CreateTypeFullName { get; set; }
+
+ public string ReturnTypeIdentifierName { get; set; }
+ public string ReturnTypeFullName { get; set; }
+
+
+
+
+ public EfAddToListModel(
+ EfEntityDataModel entity,
+ string listPropertyName,
+ string listEntityIdentifierName,
+ string listEntityFullTypeName,
+ string keyPropertyName,
+ string keyFullTypeName,
+ string createTypeIdentifierName,
+ string createTypeFullName,
+ string returnTypeIdentifierName,
+ string returnTypeFullName)
+ : base(entity.PropertyName, entity.EntityTypeFullName, entity.EntityTypeIdentifierName)
+ {
+ ListPropertyName = listPropertyName;
+ ListEntityIdentifierName = listEntityIdentifierName;
+ ListEntityFullTypeName = listEntityFullTypeName;
+ KeyPropertyName = keyPropertyName;
+ KeyFullTypeName = keyFullTypeName;
+ CreateTypeIdentifierName = createTypeIdentifierName;
+ CreateTypeFullName = createTypeFullName;
+ ReturnTypeIdentifierName = returnTypeIdentifierName;
+ ReturnTypeFullName = returnTypeFullName;
+ }
+ }
+
+
internal record SourceGenerationOptions(
AccessModifier ConstructorAccessModifier,