Skip to content

Commit

Permalink
Merge pull request #83 from esentio/feature/include
Browse files Browse the repository at this point in the history
Added support for filling properties not defined in model
  • Loading branch information
esentio authored May 26, 2021
2 parents 011b194 + 5997ad7 commit e1ef140
Show file tree
Hide file tree
Showing 74 changed files with 4,364 additions and 1,678 deletions.
3 changes: 3 additions & 0 deletions Source/Samples/Yamo.Playground.CS/Model/Article.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@ class Article
public Label Label { get; set; }
public List<ArticlePart> Parts { get; set; }
public List<Category> Categories { get; set; }
public decimal PriceWithDiscount { get; set; }
public string LabelDescription { get; set; }
public object Tag { get; set; }
}
}
2 changes: 2 additions & 0 deletions Source/Samples/Yamo.Playground.CS/Model/Category.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ class Category
{
public int Id { get; set; }
public Label Label { get; set; }

public int ArticleCount { get; set; }
}
}
59 changes: 56 additions & 3 deletions Source/Samples/Yamo.Playground.CS/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ static void Main(string[] args)
//Test44();
//Test45();
//Test46();
Test47();
//Test47();
Test48();
Test49();
Test50();
Test51();
}

public static MyContext CreateContext()
Expand Down Expand Up @@ -847,7 +851,7 @@ public static void Test46()
{
using (var db = CreateContext())
{
var blog = new Blog() { Title = "Lorem ipsum", Content = ""};
var blog = new Blog() { Title = "Lorem ipsum", Content = "" };

db.Insert<Blog>().WithHints("WITH (TABLOCK)").Execute(blog);

Expand Down Expand Up @@ -920,6 +924,55 @@ public static void Test47()
//Assert.AreEqual(15, result3.Parts[2].Price);
}
}
}
public static void Test48()
{
using (var db = CreateContext())
{
var list = db.From<Category>()
.LeftJoin<ArticleCategory>(j => j.T1.Id == j.T2.CategoryId)
.GroupBy(j => j.T1)
.SelectAll()
.ExcludeT2()
.Include(j => j.T1.ArticleCount, j => Yamo.Sql.Aggregate.Count(j.T2.ArticleId))
.ToList();
}
}

public static void Test49()
{
using (var db = CreateContext())
{
var list = db.From<Article>()
.SelectAll()
.Include(x => x.PriceWithDiscount, x => x.Price * 0.9m)
.ToList();
}
}

public static void Test50()
{
using (var db = CreateContext())
{
var list = db.From<Article>()
.LeftJoin<Label>(j => j.T1.Id == j.T2.Id)
.SelectAll()
.ExcludeT2()
.Include(j => j.T1.LabelDescription, j => j.T2.Description)
.ToList();
}
}

public static void Test51()
{
using (var db = CreateContext())
{
var list = db.From<Article>()
.LeftJoin<Label>(j => j.T1.Id == j.T2.Id)
.SelectAll()
.ExcludeT2()
.Include(j => j.T1.Tag, j => j.T2)
.ToList();
}
}
}
}
116 changes: 116 additions & 0 deletions Source/Source/Yamo.CodeGenerator/Generator/CodeGenerator.Include.vb
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
Namespace Generator

Partial Public Class CodeGenerator

Protected Sub GenerateInclude(builder As CodeBuilder, entityCount As Int32)
Dim limit = 5

If entityCount < limit Then
For i = 1 To entityCount
GenerateIncludeWithActionWithOneEntity(builder, i, entityCount)
builder.AppendLine()
Next

For i = 1 To entityCount
For j = 1 To entityCount
GenerateIncludeWithKeyValueSelectorsWithOneEntity(builder, i, j, entityCount)
builder.AppendLine()
Next
Next
End If

If 1 < entityCount Then
GenerateIncludeWithActionWithIJoin(builder, entityCount)
builder.AppendLine()

GenerateIncludeWithKeyValueSelectorsWithIJoin(builder, entityCount)
builder.AppendLine()
End If

GenerateInternalIncludeWithAction(builder, entityCount)
builder.AppendLine()

GenerateInternalIncludeWithKeyValueSelectors(builder, entityCount)
End Sub

Protected Sub GenerateIncludeWithActionWithOneEntity(builder As CodeBuilder, index As Int32, entityCount As Int32)
Dim comment = "Includes &lt;column(s)&gt; to SELECT clause."
Dim params = {"action"}
AddComment(builder, comment, params:=params, returns:="")

Dim generic = GetGenericName(index, index = entityCount)
Dim generics = String.Join(", ", GetGenericNames(entityCount))

builder.Indent().AppendLine($"Public Function Include(action As Expression(Of Action(Of {generic}))) As SelectedSelectSqlExpression(Of {generics})").PushIndent()
builder.Indent().AppendLine($"Return InternalInclude(action, {GetEntityIndexHintsForEntity(index - 1)})").PopIndent()
builder.Indent().AppendLine("End Function")
End Sub

Protected Sub GenerateIncludeWithKeyValueSelectorsWithOneEntity(builder As CodeBuilder, index1 As Int32, index2 As Int32, entityCount As Int32)
Dim comment = "Includes &lt;column(s)&gt; to SELECT clause."
Dim typeParams = {"TProperty"}
Dim params = {"keySelector", "valueSelector"}
AddComment(builder, comment, typeParams:=typeParams, params:=params, returns:="")

Dim generic1 = GetGenericName(index1, index1 = entityCount)
Dim generic2 = GetGenericName(index2, index2 = entityCount)
Dim generics = String.Join(", ", GetGenericNames(entityCount))

builder.Indent().AppendLine($"Public Function Include(Of TProperty)(keySelector As Expression(Of Func(Of {generic1}, TProperty)), valueSelector As Expression(Of Func(Of {generic2}, TProperty))) As SelectedSelectSqlExpression(Of {generics})").PushIndent()
builder.Indent().AppendLine($"Return InternalInclude(keySelector, valueSelector, {GetEntityIndexHintsForEntity(index1 - 1)}, {GetEntityIndexHintsForEntity(index2 - 1)})").PopIndent()
builder.Indent().AppendLine("End Function")
End Sub

Protected Sub GenerateIncludeWithActionWithIJoin(builder As CodeBuilder, entityCount As Int32)
Dim comment = "Includes &lt;column(s)&gt; to SELECT clause."
Dim params = {"action"}
AddComment(builder, comment, params:=params, returns:="")

Dim generics = String.Join(", ", GetGenericNames(entityCount))

builder.Indent().AppendLine($"Public Function Include(action As Expression(Of Action(Of Join(Of {generics})))) As SelectedSelectSqlExpression(Of {generics})").PushIndent()
builder.Indent().AppendLine("Return InternalInclude(action, Nothing)").PopIndent()
builder.Indent().AppendLine("End Function")
End Sub

Protected Sub GenerateIncludeWithKeyValueSelectorsWithIJoin(builder As CodeBuilder, entityCount As Int32)
Dim comment = "Includes &lt;column(s)&gt; to SELECT clause."
Dim typeParams = {"TProperty"}
Dim params = {"keySelector", "valueSelector"}
AddComment(builder, comment, typeParams:=typeParams, params:=params, returns:="")

Dim generics = String.Join(", ", GetGenericNames(entityCount))

builder.Indent().AppendLine($"Public Function Include(Of TProperty)(keySelector As Expression(Of Func(Of Join(Of {generics}), TProperty)), valueSelector As Expression(Of Func(Of Join(Of {generics}), TProperty))) As SelectedSelectSqlExpression(Of {generics})").PushIndent()
builder.Indent().AppendLine("Return InternalInclude(keySelector, valueSelector, Nothing, Nothing)").PopIndent()
builder.Indent().AppendLine("End Function")
End Sub

Protected Sub GenerateInternalIncludeWithAction(builder As CodeBuilder, entityCount As Int32)
Dim comment = "Includes &lt;column(s)&gt; to SELECT clause."
Dim params = {"action", "entityIndexHints"}
AddComment(builder, comment, params:=params, returns:="")

Dim generics = String.Join(", ", GetGenericNames(entityCount))

builder.Indent().AppendLine($"Private Function InternalInclude(action As Expression, entityIndexHints As Int32()) As SelectedSelectSqlExpression(Of {generics})").PushIndent()
builder.Indent().AppendLine("Me.Builder.IncludeToSelected(action, entityIndexHints)")
builder.Indent().AppendLine("Return Me").PopIndent()
builder.Indent().AppendLine("End Function")
End Sub

Protected Sub GenerateInternalIncludeWithKeyValueSelectors(builder As CodeBuilder, entityCount As Int32)
Dim comment = "Includes &lt;column(s)&gt; to SELECT clause."
Dim params = {"keySelector", "valueSelector", "keySelectorEntityIndexHints", "valueSelectorEntityIndexHints"}
AddComment(builder, comment, params:=params, returns:="")

Dim generics = String.Join(", ", GetGenericNames(entityCount))

builder.Indent().AppendLine($"Private Function InternalInclude(keySelector As Expression, valueSelector As Expression, keySelectorEntityIndexHints As Int32(), valueSelectorEntityIndexHints As Int32()) As SelectedSelectSqlExpression(Of {generics})").PushIndent()
builder.Indent().AppendLine("Me.Builder.IncludeToSelected(keySelector, valueSelector, keySelectorEntityIndexHints, valueSelectorEntityIndexHints)")
builder.Indent().AppendLine("Return Me").PopIndent()
builder.Indent().AppendLine("End Function")
End Sub

End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@
AddComment(builder, comment, params:=params)

builder.Indent().AppendLine("Friend Sub New(context As DbContext)").PushIndent()
builder.Indent().AppendLine("MyBase.New(New SelectSqlExpressionBuilder(context), New QueryExecutor(context))")
builder.Indent().AppendLine("Me.Builder.SetMainTable(Of T)()").PopIndent()
builder.Indent().AppendLine("MyBase.New(New SelectSqlExpressionBuilder(context, GetType(T)), New QueryExecutor(context))").PopIndent()
builder.Indent().AppendLine("End Sub")

builder.AppendLine()
Expand All @@ -100,8 +99,7 @@
AddComment(builder, comment, params:=params)

builder.Indent().AppendLine("Friend Sub New(context As DbContext, tableSource As FormattableString)").PushIndent()
builder.Indent().AppendLine("MyBase.New(New SelectSqlExpressionBuilder(context), New QueryExecutor(context))")
builder.Indent().AppendLine("Me.Builder.SetMainTable(Of T)()")
builder.Indent().AppendLine("MyBase.New(New SelectSqlExpressionBuilder(context, GetType(T)), New QueryExecutor(context))")
builder.Indent().AppendLine("Me.Builder.SetMainTableSource(tableSource)").PopIndent()
builder.Indent().AppendLine("End Sub")

Expand All @@ -112,8 +110,7 @@
AddComment(builder, comment, params:=params)

builder.Indent().AppendLine("Friend Sub New(context As DbContext, tableSource As RawSqlString, ParamArray parameters() As Object)").PushIndent()
builder.Indent().AppendLine("MyBase.New(New SelectSqlExpressionBuilder(context), New QueryExecutor(context))")
builder.Indent().AppendLine("Me.Builder.SetMainTable(Of T)()")
builder.Indent().AppendLine("MyBase.New(New SelectSqlExpressionBuilder(context, GetType(T)), New QueryExecutor(context))")
builder.Indent().AppendLine("Me.Builder.SetMainTableSource(tableSource, parameters)").PopIndent()
builder.Indent().AppendLine("End Sub")
Else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
GenerateExclude(builder, entityCount)
builder.AppendLine()

GenerateInclude(builder, entityCount)
builder.AppendLine()

GenerateDistinct(builder, entityCount)
builder.AppendLine()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Namespace Expressions.Builders
''' <summary>
''' Stores SQL model.
''' </summary>
Private m_Model As SqlModel
Private m_Model As DeleteSqlModel

''' <summary>
''' Stores whether soft delete is used.
Expand Down Expand Up @@ -58,10 +58,12 @@ Namespace Expressions.Builders
''' This API supports Yamo infrastructure and is not intended to be used directly from your code.
''' </summary>
''' <param name="context"></param>
''' <param name="mainEntityType"></param>
''' <param name="softDelete"></param>
Public Sub New(context As DbContext, softDelete As Boolean, tableNameOverride As String)
''' <param name="tableNameOverride"></param>
Public Sub New(context As DbContext, mainEntityType As Type, softDelete As Boolean, tableNameOverride As String)
MyBase.New(context)
m_Model = New SqlModel(Me.DbContext.Model)
m_Model = New DeleteSqlModel(Me.DbContext.Model, mainEntityType)
m_SoftDelete = softDelete
m_TableNameOverride = tableNameOverride
m_TableHints = Nothing
Expand All @@ -71,15 +73,6 @@ Namespace Expressions.Builders
m_ParameterIndexShift = Nothing ' lazy assigned
End Sub

''' <summary>
''' Sets main table.<br/>
''' This API supports Yamo infrastructure and is not intended to be used directly from your code.
''' </summary>
''' <typeparam name="T"></typeparam>
Public Sub SetMainTable(Of T)()
m_Model.SetMainTable(Of T)()
End Sub

''' <summary>
''' Sets table hint(s).<br/>
''' This API supports Yamo infrastructure and is not intended to be used directly from your code.
Expand All @@ -97,7 +90,7 @@ Namespace Expressions.Builders
Public Sub AddWhere(predicate As Expression)
If Not m_ParameterIndexShift.HasValue Then
If m_SoftDelete Then
m_ParameterIndexShift = m_Model.GetFirstEntity().Entity.GetSetOnDeleteProperties().Count
m_ParameterIndexShift = m_Model.MainEntity.Entity.GetSetOnDeleteProperties().Count
Else
m_ParameterIndexShift = 0
End If
Expand Down Expand Up @@ -147,7 +140,7 @@ Namespace Expressions.Builders
sql.Append("DELETE FROM ")

If m_TableNameOverride Is Nothing Then
Dim entity = m_Model.GetFirstEntity().Entity
Dim entity = m_Model.MainEntity.Entity
Me.DialectProvider.Formatter.AppendIdentifier(sql, entity.TableName, entity.Schema)
Else
sql.Append(m_TableNameOverride)
Expand All @@ -173,7 +166,7 @@ Namespace Expressions.Builders
''' </summary>
''' <returns></returns>
Private Function CreateSoftDeleteQuery() As Query
Dim entity = m_Model.GetFirstEntity().Entity
Dim entity = m_Model.MainEntity.Entity

Dim table = If(m_TableNameOverride, Me.DialectProvider.Formatter.CreateIdentifier(entity.TableName, entity.Schema))

Expand Down Expand Up @@ -217,7 +210,7 @@ Namespace Expressions.Builders
Dim table As String

If m_TableNameOverride Is Nothing Then
Dim entity = m_Model.GetFirstEntity().Entity
Dim entity = m_Model.MainEntity.Entity
table = Me.DialectProvider.Formatter.CreateIdentifier(entity.TableName, entity.Schema)
Else
table = m_TableNameOverride
Expand All @@ -243,7 +236,7 @@ Namespace Expressions.Builders
Dim table As String

If m_TableNameOverride Is Nothing Then
Dim entity = m_Model.GetFirstEntity().Entity
Dim entity = m_Model.MainEntity.Entity
table = Me.DialectProvider.Formatter.CreateIdentifier(entity.TableName, entity.Schema)
Else
table = m_TableNameOverride
Expand Down
Loading

0 comments on commit e1ef140

Please # to comment.