Add GetOneFromListTemplate
This commit is contained in:
parent
15a0f1a4f4
commit
2ac7524e8b
|
@ -4,7 +4,7 @@ using static BlueWest.EfMethods.Sources.Constants;
|
||||||
|
|
||||||
namespace BlueWest.Sources
|
namespace BlueWest.Sources
|
||||||
{
|
{
|
||||||
public class EfGetListAttributeSource
|
public static class EfGetListAttributeSource
|
||||||
{
|
{
|
||||||
internal const string AttributeName = "EfGetList";
|
internal const string AttributeName = "EfGetList";
|
||||||
internal const string AttributeClassName = AttributeName + "Attribute";
|
internal const string AttributeClassName = AttributeName + "Attribute";
|
|
@ -0,0 +1,47 @@
|
||||||
|
using BlueWest.EfMethods.Sources;
|
||||||
|
using BlueWest.EfMethods;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using static BlueWest.EfMethods.Sources.Constants;
|
||||||
|
|
||||||
|
namespace BlueWest.Sources
|
||||||
|
{
|
||||||
|
internal static class EfGetOneFromListAttributeSource
|
||||||
|
{
|
||||||
|
internal const string AttributeName = "EfGetOneFromList";
|
||||||
|
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("/// <summary>")
|
||||||
|
.WriteLine("/// Attribute for generating a function to get many entities.")
|
||||||
|
.WriteLine("/// </summary>");
|
||||||
|
|
||||||
|
|
||||||
|
builder
|
||||||
|
.WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]")
|
||||||
|
.WriteLine($"public sealed class {AttributeName}Attribute : Attribute")
|
||||||
|
.WriteOpeningBracket();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.WriteLine($"public {AttributeName}Attribute(string entityPrimaryKeyNameof, string listMemberNameof, string listPrimaryKeyNameof, Type returnType){"{}"}")
|
||||||
|
.WriteLine();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.WriteClosingBracket() // class
|
||||||
|
.WriteClosingBracket(); // namespace
|
||||||
|
|
||||||
|
return new(builder.ToString(), $"{AttributeName}Attribute.g.cs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ namespace BlueWest.EfMethods.Sources
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.WriteLine("/// <summary>")
|
.WriteLine("/// <summary>")
|
||||||
.WriteLine("/// Generate update methods for this Db<Set> property")
|
.WriteLine("/// Generate update methods this EF entity")
|
||||||
.WriteLine("/// </summary>");
|
.WriteLine("/// </summary>");
|
||||||
|
|
||||||
builder
|
builder
|
|
@ -276,6 +276,7 @@ namespace BlueWest.EfMethods
|
||||||
var efGetManyMembers = GetAllowedMemberSyntaxes(EfGetManyAttributeSource.AttributeName);
|
var efGetManyMembers = GetAllowedMemberSyntaxes(EfGetManyAttributeSource.AttributeName);
|
||||||
var getListMembers = GetAllowedMemberSyntaxes(EfGetListAttributeSource.AttributeName);
|
var getListMembers = GetAllowedMemberSyntaxes(EfGetListAttributeSource.AttributeName);
|
||||||
var getAddToListMembers = GetAllowedMemberSyntaxes(EfAddToListAttributeSource.AttributeName);
|
var getAddToListMembers = GetAllowedMemberSyntaxes(EfAddToListAttributeSource.AttributeName);
|
||||||
|
var getOneFromListMembers = GetAllowedMemberSyntaxes(EfGetOneFromListAttributeSource.AttributeName);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -334,10 +335,12 @@ namespace BlueWest.EfMethods
|
||||||
methodsModels.Add(newModel);
|
methodsModels.Add(newModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var uProperty in getOneFromListMembers)
|
||||||
|
{
|
||||||
|
var entityDataModel = GetEntityData(uProperty, semanticModel);
|
||||||
//SpinWait.SpinUntil(() => Debugger.IsAttached);
|
var newModel = ExtractEfGetOneFromListMethodsModel(uProperty, semanticModel, entityDataModel);
|
||||||
|
methodsModels.Add(newModel);
|
||||||
|
}
|
||||||
|
|
||||||
return new EfMethodsModel(
|
return new EfMethodsModel(
|
||||||
SourceGenerationOptions,
|
SourceGenerationOptions,
|
||||||
|
@ -546,9 +549,6 @@ namespace BlueWest.EfMethods
|
||||||
private EfAddToListModel ExtractEfAddToListMethodsModel(MemberDeclarationSyntax uProperty, SemanticModel semanticModel, EfEntityDataModel entityDataModel)
|
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 listPropertyName = ExtractNameOfMemberName(uProperty, EfAddToListAttributeSource.AttributeName, semanticModel);
|
||||||
var keyPropertyName = ExtractNameOfMemberName(uProperty, EfAddToListAttributeSource.AttributeName, semanticModel, 1);;
|
var keyPropertyName = ExtractNameOfMemberName(uProperty, EfAddToListAttributeSource.AttributeName, semanticModel, 1);;
|
||||||
|
@ -574,6 +574,8 @@ namespace BlueWest.EfMethods
|
||||||
var createTypeIdentifierName =listEntityIdentifierName;
|
var createTypeIdentifierName =listEntityIdentifierName;
|
||||||
var createTypeFullName = listEntityFullTypeName;
|
var createTypeFullName = listEntityFullTypeName;
|
||||||
|
|
||||||
|
var efTypeofSymbols = GetEntityTypeSymbol(uProperty, EfAddToListAttributeSource.AttributeName, semanticModel);
|
||||||
|
|
||||||
// Grab create type from attribute argument
|
// Grab create type from attribute argument
|
||||||
if (efTypeofSymbols.Length > 0)
|
if (efTypeofSymbols.Length > 0)
|
||||||
{
|
{
|
||||||
|
@ -602,6 +604,51 @@ namespace BlueWest.EfMethods
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private EfGetOneFromListModel ExtractEfGetOneFromListMethodsModel(MemberDeclarationSyntax uProperty, SemanticModel semanticModel, EfEntityDataModel entityDataModel)
|
||||||
|
{
|
||||||
|
|
||||||
|
//SpinWait.SpinUntil(() => Debugger.IsAttached);
|
||||||
|
|
||||||
|
var efTypeofSymbols = GetEntityTypeSymbol(uProperty, EfGetOneFromListAttributeSource.AttributeName, semanticModel);
|
||||||
|
var attributeSymbol = uProperty.GetAttribute(EfGetOneFromListAttributeSource.AttributeName);
|
||||||
|
var keyPropertyName = ExtractNameOfMemberName(uProperty, EfGetOneFromListAttributeSource.AttributeName, semanticModel);
|
||||||
|
var listKeyPropertyName = ExtractNameOfMemberName(uProperty, EfGetOneFromListAttributeSource.AttributeName, semanticModel, 2);
|
||||||
|
var keyMemberType = FindTypeInfoOfMemberExpressionSyntax(semanticModel, attributeSymbol);
|
||||||
|
var listKeyTypeInfo = FindTypeInfoOfMemberExpressionSyntax(semanticModel, attributeSymbol, 0);
|
||||||
|
var keyFullTypeName = keyMemberType.Value.Type.ToDisplayString();
|
||||||
|
var listEntityTypeInfo = (FindTypeInfoOfMemberExpressionSyntax(semanticModel, attributeSymbol, 1).Value.Type as INamedTypeSymbol).TypeArguments.FirstOrDefault();
|
||||||
|
var listEntityIdentifierName = listEntityTypeInfo.Name;
|
||||||
|
var listEntityFullTypeName = listEntityTypeInfo.ToDisplayString();
|
||||||
|
var listKeyFullTypeName =listKeyTypeInfo.Value.Type.ToDisplayString();;
|
||||||
|
var listKeyTypeName = listKeyTypeInfo.Value.Type.Name;
|
||||||
|
var listPropertyName = ExtractNameOfMemberName(uProperty, EfGetOneFromListAttributeSource.AttributeName, semanticModel, 1);;
|
||||||
|
|
||||||
|
|
||||||
|
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 EfGetOneFromListModel(
|
||||||
|
entityDataModel,
|
||||||
|
listPropertyName,
|
||||||
|
listEntityIdentifierName,
|
||||||
|
listEntityFullTypeName,
|
||||||
|
keyPropertyName,
|
||||||
|
keyFullTypeName,
|
||||||
|
listKeyPropertyName,
|
||||||
|
listKeyFullTypeName,
|
||||||
|
listKeyTypeName,
|
||||||
|
returnTypeIdentifierName,
|
||||||
|
returnTypeFullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static ITypeSymbol GetEntityTypeData(MemberDeclarationSyntax memberDeclarationSyntax, SemanticModel? semanticModel = null)
|
private static ITypeSymbol GetEntityTypeData(MemberDeclarationSyntax memberDeclarationSyntax, SemanticModel? semanticModel = null)
|
||||||
{
|
{
|
||||||
var member = (memberDeclarationSyntax as PropertyDeclarationSyntax).Type;
|
var member = (memberDeclarationSyntax as PropertyDeclarationSyntax).Type;
|
|
@ -39,7 +39,8 @@ namespace BlueWest.EfMethods
|
||||||
.AddSource(ref context, EfGetOneAttributeSource.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, EfGetListAttributeSource.Generate(options))
|
||||||
.AddSource(ref context, EfAddToListAttributeSource.Generate(options));
|
.AddSource(ref context, EfAddToListAttributeSource.Generate(options))
|
||||||
|
.AddSource(ref context, EfGetOneFromListAttributeSource.Generate(options));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,6 +66,8 @@ namespace BlueWest.EfMethods
|
||||||
string getManyWithTemplate = GetCsxMethodTemplate(context, "GetManyTemplate");
|
string getManyWithTemplate = GetCsxMethodTemplate(context, "GetManyTemplate");
|
||||||
string getListTemplate = GetCsxMethodTemplate(context, "GetListTemplate");
|
string getListTemplate = GetCsxMethodTemplate(context, "GetListTemplate");
|
||||||
string addToListTemplate = GetCsxMethodTemplate(context, "AddToListTemplate");
|
string addToListTemplate = GetCsxMethodTemplate(context, "AddToListTemplate");
|
||||||
|
string getOneFromListTemplate = GetCsxMethodTemplate(context, "GetOneFromListTemplate");
|
||||||
|
|
||||||
|
|
||||||
return new EfTemplates(
|
return new EfTemplates(
|
||||||
addSourceTemplate,
|
addSourceTemplate,
|
||||||
|
@ -73,7 +76,9 @@ namespace BlueWest.EfMethods
|
||||||
getOneTemplate,
|
getOneTemplate,
|
||||||
getManyWithTemplate,
|
getManyWithTemplate,
|
||||||
getListTemplate,
|
getListTemplate,
|
||||||
addToListTemplate);
|
addToListTemplate,
|
||||||
|
getOneFromListTemplate
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddGeneratedExtensions(GeneratorExecutionContext context, Compilation compilation, IEnumerable<TypeDeclarationSyntax> candidateMembers, SourceGenerationOptions options)
|
private static void AddGeneratedExtensions(GeneratorExecutionContext context, Compilation compilation, IEnumerable<TypeDeclarationSyntax> candidateMembers, SourceGenerationOptions options)
|
|
@ -64,6 +64,7 @@ namespace BlueWest.EfMethods.Sources
|
||||||
.EfAddGetOneMethod(model, currentModel, templates.GetOneTemplate)
|
.EfAddGetOneMethod(model, currentModel, templates.GetOneTemplate)
|
||||||
.WriteLine();
|
.WriteLine();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EfGetListModel currentModel:
|
case EfGetListModel currentModel:
|
||||||
builder
|
builder
|
||||||
.EfAddGetListMethod(model, currentModel, templates.GetListTemplate)
|
.EfAddGetListMethod(model, currentModel, templates.GetListTemplate)
|
||||||
|
@ -75,6 +76,12 @@ namespace BlueWest.EfMethods.Sources
|
||||||
.WriteLine();
|
.WriteLine();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EfGetOneFromListModel currentModel:
|
||||||
|
builder
|
||||||
|
.EfAddGetOneFromListMethod(model, currentModel, templates.GetOneFromListTemplate)
|
||||||
|
.WriteLine();
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
using BlueWest.EfMethods.Extensions;
|
||||||
|
using BlueWest.EfMethods.Sources;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace BlueWest.EfMethods
|
||||||
|
{
|
||||||
|
internal static class EfGetOneFromListTemplateSource
|
||||||
|
{
|
||||||
|
internal static SourceBuilder EfAddGetOneFromListMethod(this SourceBuilder builder, EfMethodsModel methodsModel, EfGetOneFromListModel model, string addSourceTemplate)
|
||||||
|
{
|
||||||
|
var returnTypeFullName = model.ReturnTypeFullName;
|
||||||
|
var entityTypeName = model.EntityTypeIdentifierName;
|
||||||
|
var propertyName = model.PropertyName;
|
||||||
|
var listItemTypeName = model.ListEntityIdentifierName;
|
||||||
|
|
||||||
|
var contextFullName = methodsModel.ContextFullType;
|
||||||
|
var primaryKeyFullName = model.KeyFullTypeName;
|
||||||
|
var primaryKeyVarName = $"{model.EntityTypeIdentifierName}{model.KeyPropertyName}".ToCamelCase();
|
||||||
|
|
||||||
|
var listPrimaryKeyFullName = model.ListKeyFullTypeName;
|
||||||
|
var listPrimaryKeyVarName = $"{model.ListEntityIdentifierName}{model.ListKeyPropertyName}".ToCamelCase();
|
||||||
|
var listPropertyName = model.ListPropertyName;
|
||||||
|
var listPrimaryKeyPropertyName = model.ListKeyPropertyName;
|
||||||
|
|
||||||
|
var primaryKeyPropertyName = model.KeyPropertyName;
|
||||||
|
|
||||||
|
if (!addSourceTemplate.IsEmpty())
|
||||||
|
{
|
||||||
|
var templateToSourceBuilder = new StringBuilder(addSourceTemplate);
|
||||||
|
templateToSourceBuilder
|
||||||
|
.Replace("{returnTypeFullName}", returnTypeFullName)
|
||||||
|
.Replace("{entityTypeName}", entityTypeName)
|
||||||
|
.Replace("{listItemTypeName}", listItemTypeName)
|
||||||
|
.Replace("{contextFullName}", contextFullName)
|
||||||
|
.Replace("{primaryKeyPropertyName}", primaryKeyPropertyName)
|
||||||
|
.Replace("{listPrimaryKeyPropertyName}", listPrimaryKeyPropertyName)
|
||||||
|
|
||||||
|
.Replace("{primaryKeyFullName}", primaryKeyFullName)
|
||||||
|
.Replace("{primaryKeyVarName}", primaryKeyVarName)
|
||||||
|
.Replace("{listPrimaryKeyFullName}", listPrimaryKeyFullName)
|
||||||
|
.Replace("{listPrimaryKeyVarName}", listPrimaryKeyVarName)
|
||||||
|
.Replace("{listPropertyName}", listPropertyName)
|
||||||
|
|
||||||
|
.Replace("{propertyName}", propertyName);
|
||||||
|
|
||||||
|
builder
|
||||||
|
.ParseTemplate(templateToSourceBuilder.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addSourceTemplate.IsEmpty())
|
||||||
|
{
|
||||||
|
builder
|
||||||
|
.WriteComment("Generated body")
|
||||||
|
//.WriteLine(GeneratedFilesHeader)
|
||||||
|
.WriteLine($"public static (bool, {returnTypeFullName}) Get{listItemTypeName}From{entityTypeName} (this {contextFullName} dbContext, {primaryKeyFullName} {primaryKeyVarName},")
|
||||||
|
.WriteLine($"{listPrimaryKeyFullName} {listPrimaryKeyVarName})")
|
||||||
|
.WriteOpeningBracket()
|
||||||
|
.WriteLine($"var query =")
|
||||||
|
.WriteLine($"from mainEntity in dbContext.{propertyName}")
|
||||||
|
.WriteLine($"where mainEntity.{primaryKeyPropertyName} == {primaryKeyVarName}")
|
||||||
|
.WriteLine($"let list = mainEntity.{listPropertyName}")
|
||||||
|
.WriteLine($"from listItem in list")
|
||||||
|
.WriteLine($"where listItem.{listPrimaryKeyPropertyName} == {listPrimaryKeyVarName}")
|
||||||
|
.WriteLine($"select new {returnTypeFullName}(listItem);")
|
||||||
|
.WriteLine()
|
||||||
|
.WriteLine("query = countryQuery.SingleOrDefault();")
|
||||||
|
.WriteLine("return (query != null, query);")
|
||||||
|
.WriteClosingBracket();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,7 +40,8 @@ namespace BlueWest.EfMethods
|
||||||
string GetOneTemplate,
|
string GetOneTemplate,
|
||||||
string GetManyTemplate,
|
string GetManyTemplate,
|
||||||
string GetListTemplate,
|
string GetListTemplate,
|
||||||
string AddToListTemplate
|
string AddToListTemplate,
|
||||||
|
string GetOneFromListTemplate
|
||||||
);
|
);
|
||||||
|
|
||||||
internal class EfEntityDataModel
|
internal class EfEntityDataModel
|
||||||
|
@ -223,6 +224,56 @@ namespace BlueWest.EfMethods
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class EfGetOneFromListModel : 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 ListKeyPropertyName { get; set; }
|
||||||
|
public string ListKeyFullTypeName { get; set; }
|
||||||
|
|
||||||
|
public string ListKeyTypeName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public string ReturnTypeIdentifierName { get; set; }
|
||||||
|
public string ReturnTypeFullName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public EfGetOneFromListModel(
|
||||||
|
EfEntityDataModel entity,
|
||||||
|
string listPropertyName,
|
||||||
|
string listEntityIdentifierName,
|
||||||
|
string listEntityFullTypeName,
|
||||||
|
string keyPropertyName,
|
||||||
|
string keyFullTypeName,
|
||||||
|
string listKeyPropertyName,
|
||||||
|
string listKeyFullTypeName,
|
||||||
|
string listKeyTypeName,
|
||||||
|
string returnTypeIdentifierName,
|
||||||
|
string returnTypeFullName)
|
||||||
|
: base(entity.PropertyName, entity.EntityTypeFullName, entity.EntityTypeIdentifierName)
|
||||||
|
{
|
||||||
|
ListPropertyName = listPropertyName;
|
||||||
|
ListEntityIdentifierName = listEntityIdentifierName;
|
||||||
|
ListEntityFullTypeName = listEntityFullTypeName;
|
||||||
|
KeyPropertyName = keyPropertyName;
|
||||||
|
KeyFullTypeName = keyFullTypeName;
|
||||||
|
ListKeyPropertyName = listKeyPropertyName;
|
||||||
|
ListKeyFullTypeName = listKeyFullTypeName;
|
||||||
|
ListKeyTypeName = listKeyTypeName;
|
||||||
|
ReturnTypeIdentifierName = returnTypeIdentifierName;
|
||||||
|
ReturnTypeFullName = returnTypeFullName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal record SourceGenerationOptions(
|
internal record SourceGenerationOptions(
|
||||||
|
|
Loading…
Reference in New Issue