Skip to content

Commit

Permalink
add PgArrayToMany LazyLoding test #1145
Browse files Browse the repository at this point in the history
  • Loading branch information
2881099 committed Jun 6, 2022
1 parent a50c14e commit b93a487
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 17 deletions.
9 changes: 0 additions & 9 deletions FreeSql.DbContext/FreeSql.DbContext.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

120 changes: 120 additions & 0 deletions FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLPgArrayToManyTest .cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
using FreeSql.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Xunit;

namespace FreeSql.Tests.PostgreSQL
{
public class PostgreSQLPgArrayToManyTest
{

[Table(Name = "pgarray_tomany_user_lazyloading")]
public class UserLazyLoading
{
public int Id { get; set; }
public int[] RoleIds { get; set; }
public string UserName { get; set; }

[Navigate(nameof(RoleIds))]
public virtual List<RoleLazyLoading> Roles { get; set; }
}

[Table(Name = "pgarray_tomany_role_lazyloading")]
public class RoleLazyLoading
{
public int Id { get; set; }
public string RoleName { get; set; }

[Navigate(nameof(UserLazyLoading.RoleIds))]
public virtual List<UserLazyLoading> Users { get; set; }
}

[Fact]
public void LazyLoading()
{
var fsql = g.pgsql;
fsql.Delete<UserLazyLoading>().Where("1=1").ExecuteAffrows();
fsql.Delete<RoleLazyLoading>().Where("1=1").ExecuteAffrows();

var roles = new[]
{
new RoleLazyLoading { Id = 1, RoleName = "role1" },
new RoleLazyLoading { Id = 2, RoleName = "role2" },
new RoleLazyLoading { Id = 3, RoleName = "role3" }
};
Assert.Equal(3, fsql.Insert(roles).ExecuteAffrows());
var users = new[]
{
new UserLazyLoading { Id = 11, RoleIds = new [] { 1,2 }, UserName = "user1" },
new UserLazyLoading { Id = 12, RoleIds = new [] { 1,2,3 }, UserName = "user2" },
new UserLazyLoading { Id = 13, RoleIds = new [] { 1,3 }, UserName = "user3" },
new UserLazyLoading { Id = 14, RoleIds = new [] { 3,2,1 }, UserName = "user4" },
new UserLazyLoading { Id = 15, RoleIds = null, UserName = "user5" },
new UserLazyLoading { Id = 16, RoleIds = new int[0], UserName = "user6" },
};
Assert.Equal(6, fsql.Insert(users).ExecuteAffrows());

var role = fsql.Select<RoleLazyLoading>().Where(a => a.Id == 1).First();
Assert.IsNotType<RoleLazyLoading>(role);

var users2 = role.Users;
Assert.Equal(4, users2.Count);
Assert.Equal(11, users2[0].Id);
Assert.Equal("user1", users2[0].UserName);
Assert.Equal("1,2", string.Join(",", users2[0].RoleIds));
Assert.Equal(12, users2[1].Id);
Assert.Equal("user2", users2[1].UserName);
Assert.Equal("1,2,3", string.Join(",", users2[1].RoleIds));
Assert.Equal(13, users2[2].Id);
Assert.Equal("user3", users2[2].UserName);
Assert.Equal("1,3", string.Join(",", users2[2].RoleIds));
Assert.Equal(14, users2[3].Id);
Assert.Equal("user4", users2[3].UserName);
Assert.Equal("3,2,1", string.Join(",", users2[3].RoleIds));

var roles2 = users2[0].Roles;
Assert.Equal(2, roles2.Count);
Assert.Equal(1, roles2[0].Id);
Assert.Equal("role1", roles2[0].RoleName);
Assert.Equal(2, roles2[1].Id);
Assert.Equal("role2", roles2[1].RoleName);

roles2 = users2[1].Roles;
Assert.Equal(3, roles2.Count);
Assert.Equal(1, roles2[0].Id);
Assert.Equal("role1", roles2[0].RoleName);
Assert.Equal(2, roles2[1].Id);
Assert.Equal("role2", roles2[1].RoleName);
Assert.Equal(3, roles2[2].Id);
Assert.Equal("role3", roles2[2].RoleName);

roles2 = users2[2].Roles;
Assert.Equal(2, roles2.Count);
Assert.Equal(1, roles2[0].Id);
Assert.Equal("role1", roles2[0].RoleName);
Assert.Equal(3, roles2[1].Id);
Assert.Equal("role3", roles2[1].RoleName);

roles2 = users2[3].Roles;
Assert.Equal(3, roles2.Count);
Assert.Equal(3, roles2[0].Id);
Assert.Equal("role3", roles2[0].RoleName);
Assert.Equal(2, roles2[1].Id);
Assert.Equal("role2", roles2[1].RoleName);
Assert.Equal(1, roles2[2].Id);
Assert.Equal("role1", roles2[2].RoleName);

var user = fsql.Select<UserLazyLoading>().Where(a => a.Id == 11).First();
Assert.IsNotType<UserLazyLoading>(user);

roles2 = user.Roles;
Assert.Equal(2, roles2.Count);
Assert.Equal(1, roles2[0].Id);
Assert.Equal("role1", roles2[0].RoleName);
Assert.Equal(2, roles2[1].Id);
Assert.Equal("role2", roles2[1].RoleName);
}
}
}
2 changes: 1 addition & 1 deletion FreeSql/Internal/CommonExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2201,7 +2201,7 @@ void LocalSetSelectProviderAlias(string alias)
midSelect.Where($"{midSelect._tables[0].Alias}.{commonExp._common.QuoteSqlName(memberTbref.MiddleColumns[memberTbref.Columns.Count + tidx].Attribute.Name)} = {select._tables[0].Alias}.{commonExp._common.QuoteSqlName(memberTbref.RefColumns[tidx].Attribute.Name)}");
for (var tidx = 0; tidx < memberTbref.Columns.Count; tidx++)
midSelect.Where($"{midSelect._tables[0].Alias}.{commonExp._common.QuoteSqlName(memberTbref.MiddleColumns[tidx].Attribute.Name)} = {mtmReftbname}.{commonExp._common.QuoteSqlName(memberTbref.Columns[tidx].Attribute.Name)}");
select.Where($"exists({midSelect.ToSql("1").Replace(" \r\n", " \r\n ")})");
select._where.Append($" AND exists({midSelect.ToSql("1").Replace(" \r\n", " \r\n ")})");
break;
case TableRefType.OneToMany:
var omtReftbname = e.FreeParse(Expression.MakeMemberAccess(memberExp.Expression, exp3Tb.Properties[exp3Tb.ColumnsByPosition[0].CsName]));
Expand Down
20 changes: 13 additions & 7 deletions FreeSql/Internal/UtilsExpressionTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -969,9 +969,10 @@ public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo
.Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {");

if (nvref.Exception == null)
cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.DisplayCsharp())
cscode.Append(" var loc2 = __fsql_orm__.Select<").Append(propElementType.DisplayCsharp())
.Append(">().Where(a => __fsql_orm__.Select<").Append(tbmid.Type.DisplayCsharp())
.Append(">().Where(b => ").Append(lmbdWhere.ToString()).AppendLine(").Any()).ToList();")
.Append(" base.").Append(pnv.Name).Append(" = ").AppendLine(propTypeIsObservableCollection ? $"new ObservableCollection<{propElementType.DisplayCsharp()}>(loc2);" : "loc2;")
.Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;");
else
cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");");
Expand All @@ -994,7 +995,8 @@ public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo
{
var isArrayToMany = false;
var lmbdWhere = isLazy ? new StringBuilder() : null;
var cscodeExtLogic = "";
var cscodeExtLogic1 = "";
var cscodeExtLogic2 = "";
//Pgsql Array[] To Many
if (common._orm.Ado.DataType == DataType.PostgreSQL)
{
Expand Down Expand Up @@ -1042,7 +1044,8 @@ public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo
isArrayToMany = trycol != null;
if (isArrayToMany)
{
cscodeExtLogic = $" if (this.{trycol.CsName} == null) return null; \r\nif (this.{trycol.CsName}.Any() == false) return new {(propTypeIsObservableCollection ? "ObservableCollection" : "List")}<{propElementType.DisplayCsharp()}>();\r\n";
cscodeExtLogic1 = $" if (this.{trycol.CsName} == null) return null; \r\nif (this.{trycol.CsName}.Any() == false) return new {(propTypeIsObservableCollection ? "ObservableCollection" : "List")}<{propElementType.DisplayCsharp()}>();\r\n";
cscodeExtLogic2 = $" loc2 = this.{trycol.CsName}.Select(a => loc2.FirstOrDefault(b => b.{tbref.Primarys[0].CsName} == a)).ToList();";
lmbdWhere.Append("this.").Append(trycol.CsName).Append(".Contains(a.").Append(tbref.Primarys[0].CsName);
if (trycol.CsType.GetElementType().IsNullableType() == false && tbref.Primarys[0].CsType.IsNullableType()) lmbdWhere.Append(".Value");
lmbdWhere.Append(")");
Expand Down Expand Up @@ -1092,7 +1095,7 @@ public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo
if (trycol.CsType.GetElementType().IsNullableType() == false && trytb.Primarys[0].CsType.IsNullableType())
{
lmbdWhere.Append(".Value");
cscodeExtLogic = $" if (this.{trytb.Primarys[0].CsName} == null) return null;\r\n";
cscodeExtLogic1 = $" if (this.{trytb.Primarys[0].CsName} == null) return null;\r\n";
}
lmbdWhere.Append(")");
nvref.Columns.Add(tbref.Primarys[0]);
Expand Down Expand Up @@ -1219,12 +1222,14 @@ public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo
if (vp?.Item2 == true)
{ //get 重写
cscode.Append(" ").Append(propGetModification).Append(" get {\r\n")
.Append(cscodeExtLogic)
.Append(cscodeExtLogic1)
.Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {");

if (nvref.Exception == null)
{
cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propElementType.DisplayCsharp()).Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToList();");
cscode.Append(" var loc2 = __fsql_orm__.Select<").Append(propElementType.DisplayCsharp()).Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToList();")
.Append(cscodeExtLogic2)
.Append(" base.").Append(pnv.Name).Append(" = ").AppendLine(propTypeIsObservableCollection ? $"new ObservableCollection<{propElementType.DisplayCsharp()}>(loc2);" : "loc2;");
if (refprop != null)
{
cscode.Append(" foreach (var loc1 in base.").Append(pnv.Name).AppendLine(")")
Expand Down Expand Up @@ -1381,7 +1386,8 @@ public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo
.Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {");

if (nvref.Exception == null)
cscode.Append(" base.").Append(pnv.Name).Append(" = __fsql_orm__.Select<").Append(propTypeName).Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToOne();")
cscode.Append(" var loc3 = __fsql_orm__.Select<").Append(propTypeName).Append(">().Where(a => ").Append(lmbdWhere.ToString()).AppendLine(").ToOne();")
.Append(" base.").Append(pnv.Name).AppendLine(" = loc3;")
.Append(" __lazy__").Append(pnv.Name).AppendLine(" = true;");
else
cscode.Append(" throw new Exception(\"").Append(nvref.Exception.Message.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")).AppendLine("\");");
Expand Down

0 comments on commit b93a487

Please sign in to comment.