From 679cf7efca2c28e44bbde70cb78369fe3c11c512 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Fri, 24 Feb 2023 21:33:27 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=93=8D=E4=BD=9C=20.IncludeByPropertyName?= =?UTF-8?q?=20=E4=B9=8B=E5=90=8E=E7=9A=84=20then.WhereDynamicFilter=20?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AspNetRoleClaims/AspNetRoleClaims.cs | 36 +++++ .../AspNetRoleClaims/AspNetRoles.cs | 39 +++++ .../AspNetRoleClaims/AspNetUserClaims.cs | 39 +++++ .../AspNetRoleClaims/AspNetUserLogins.cs | 39 +++++ .../AspNetRoleClaims/AspNetUserRoles.cs | 45 ++++++ .../AspNetRoleClaims/AspNetUserTokens.cs | 36 +++++ .../AspNetRoleClaims/AspNetUsers.cs | 149 ++++++++++++++++++ .../AspNetRoleClaims/DeviceCodes.cs | 53 +++++++ Examples/base_entity/AspNetRoleClaims/Keys.cs | 49 ++++++ .../AspNetRoleClaims/PersistedGrants.cs | 57 +++++++ .../AspNetRoleClaims/WebAppIdentityUser.cs | 53 +++++++ .../base_entity/AspNetRoleClaims/ids_api.db | Bin 0 -> 172032 bytes Examples/base_entity/Program.cs | 13 +- Examples/base_entity/base_entity.xml | 71 +++++++++ .../SelectProvider/Select1Provider.cs | 8 + 15 files changed, 684 insertions(+), 3 deletions(-) create mode 100644 Examples/base_entity/AspNetRoleClaims/AspNetRoleClaims.cs create mode 100644 Examples/base_entity/AspNetRoleClaims/AspNetRoles.cs create mode 100644 Examples/base_entity/AspNetRoleClaims/AspNetUserClaims.cs create mode 100644 Examples/base_entity/AspNetRoleClaims/AspNetUserLogins.cs create mode 100644 Examples/base_entity/AspNetRoleClaims/AspNetUserRoles.cs create mode 100644 Examples/base_entity/AspNetRoleClaims/AspNetUserTokens.cs create mode 100644 Examples/base_entity/AspNetRoleClaims/AspNetUsers.cs create mode 100644 Examples/base_entity/AspNetRoleClaims/DeviceCodes.cs create mode 100644 Examples/base_entity/AspNetRoleClaims/Keys.cs create mode 100644 Examples/base_entity/AspNetRoleClaims/PersistedGrants.cs create mode 100644 Examples/base_entity/AspNetRoleClaims/WebAppIdentityUser.cs create mode 100644 Examples/base_entity/AspNetRoleClaims/ids_api.db diff --git a/Examples/base_entity/AspNetRoleClaims/AspNetRoleClaims.cs b/Examples/base_entity/AspNetRoleClaims/AspNetRoleClaims.cs new file mode 100644 index 00000000..b59f86a1 --- /dev/null +++ b/Examples/base_entity/AspNetRoleClaims/AspNetRoleClaims.cs @@ -0,0 +1,36 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System.ComponentModel; +#nullable disable + +namespace Densen.Models.ids +{ + + /// + /// 角色声明 + /// + [JsonObject(MemberSerialization.OptIn), Table(DisableSyncStructure = true)] + public partial class AspNetRoleClaims + { + + [DisplayName("ID")] + [JsonProperty, Column(IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } + + [DisplayName("角色ID")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string RoleId { get; set; } + + [DisplayName("角色声明")] + [JsonProperty, Column(StringLength = -2)] + public string ClaimType { get; set; } + + [DisplayName("值")] + [JsonProperty, Column(StringLength = -2)] + public string ClaimValue { get; set; } + + [Navigate(nameof(RoleId))] + public virtual AspNetRoles AspNetRoles { get; set; } + + } +} \ No newline at end of file diff --git a/Examples/base_entity/AspNetRoleClaims/AspNetRoles.cs b/Examples/base_entity/AspNetRoleClaims/AspNetRoles.cs new file mode 100644 index 00000000..113c62db --- /dev/null +++ b/Examples/base_entity/AspNetRoleClaims/AspNetRoles.cs @@ -0,0 +1,39 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System.Collections.Generic; +using System.ComponentModel; +#nullable disable + +namespace Densen.Models.ids +{ + + /// + /// 角色定义 + /// + [JsonObject(MemberSerialization.OptIn), Table(DisableSyncStructure = true)] + public partial class AspNetRoles + { + + [DisplayName("ID")] + [JsonProperty, Column(StringLength = -2, IsPrimary = true, IsNullable = false)] + public string Id { get; set; } + + [DisplayName("角色")] + [JsonProperty, Column(StringLength = -2)] + public string Name { get; set; } + + [DisplayName("标准化名称")] + [JsonProperty, Column(StringLength = -2)] + public string NormalizedName { get; set; } + + [DisplayName("并发票据")] + [JsonProperty, Column(StringLength = -2)] + public string ConcurrencyStamp { get; set; } + + //导航属性 + [Navigate(nameof(AspNetUserRoles.RoleId))] + [DisplayName("角色表")] + public virtual List AspNetUserRoless { get; set; } + + } +} \ No newline at end of file diff --git a/Examples/base_entity/AspNetRoleClaims/AspNetUserClaims.cs b/Examples/base_entity/AspNetRoleClaims/AspNetUserClaims.cs new file mode 100644 index 00000000..36fac428 --- /dev/null +++ b/Examples/base_entity/AspNetRoleClaims/AspNetUserClaims.cs @@ -0,0 +1,39 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System.ComponentModel; +#nullable disable + +namespace Densen.Models.ids +{ + + /// + /// 用户声明 + /// + [JsonObject(MemberSerialization.OptIn), Table(DisableSyncStructure = true)] + public partial class AspNetUserClaims + { + + [DisplayName("ID")] + [JsonProperty, Column(IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } + + [DisplayName("用户ID")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string UserId { get; set; } + + [DisplayName("声明类型")] + [JsonProperty, Column(StringLength = -2)] + public string ClaimType { get; set; } + + [DisplayName("值")] + [JsonProperty, Column(StringLength = -2)] + public string ClaimValue { get; set; } + + /// + /// 用户 + /// + [Navigate(nameof(UserId))] + public virtual AspNetUsers AspNetUsers { get; set; } + + } +} \ No newline at end of file diff --git a/Examples/base_entity/AspNetRoleClaims/AspNetUserLogins.cs b/Examples/base_entity/AspNetRoleClaims/AspNetUserLogins.cs new file mode 100644 index 00000000..1ac800f6 --- /dev/null +++ b/Examples/base_entity/AspNetRoleClaims/AspNetUserLogins.cs @@ -0,0 +1,39 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System.ComponentModel; +#nullable disable + +namespace Densen.Models.ids +{ + + /// + /// 用户登录 + /// + [JsonObject(MemberSerialization.OptIn), Table(DisableSyncStructure = true)] + public partial class AspNetUserLogins + { + + [DisplayName("外联登录")] + [JsonProperty, Column(StringLength = -2, IsPrimary = true, IsNullable = false)] + public string LoginProvider { get; set; } + + [DisplayName("用户ID")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string UserId { get; set; } + + [DisplayName("外联Key")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string ProviderKey { get; set; } + + [DisplayName("外联名称")] + [JsonProperty, Column(StringLength = -2)] + public string ProviderDisplayName { get; set; } + + /// + /// 用户 + /// + [Navigate(nameof(UserId))] + public virtual AspNetUsers AspNetUsers { get; set; } + + } +} \ No newline at end of file diff --git a/Examples/base_entity/AspNetRoleClaims/AspNetUserRoles.cs b/Examples/base_entity/AspNetRoleClaims/AspNetUserRoles.cs new file mode 100644 index 00000000..30c4e044 --- /dev/null +++ b/Examples/base_entity/AspNetRoleClaims/AspNetUserRoles.cs @@ -0,0 +1,45 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System.ComponentModel; +#nullable disable + +namespace Densen.Models.ids +{ + + /// + /// 角色表 + /// 存储向哪些用户分配哪些角色 + /// + [JsonObject(MemberSerialization.OptIn), Table(DisableSyncStructure = true)] + public partial class AspNetUserRoles + { + + [DisplayName("用户ID")] + [JsonProperty, Column(StringLength = -2, IsPrimary = true, IsNullable = false)] + public string UserId { get; set; } + + [JsonProperty, Column(IsIgnore = true)] + [DisplayName("用户")] + public string UserName { get => roleName ?? (AspNetUserss?.UserName); set => userName = value; } + string userName; + + [DisplayName("角色ID")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string RoleId { get; set; } + + [JsonProperty, Column(IsIgnore = true)] + [DisplayName("角色名称")] + public string RoleName { get => roleName ?? (AspNetRoless?.Name); set => roleName = value; } + string roleName; + + [DisplayName("角色定义")] + [Navigate(nameof(RoleId))] + public virtual AspNetRoles AspNetRoless { get; set; } + + [DisplayName("用户表")] + [Navigate(nameof(UserId))] + public virtual AspNetUsers AspNetUserss { get; set; } + + } + +} \ No newline at end of file diff --git a/Examples/base_entity/AspNetRoleClaims/AspNetUserTokens.cs b/Examples/base_entity/AspNetRoleClaims/AspNetUserTokens.cs new file mode 100644 index 00000000..669ef390 --- /dev/null +++ b/Examples/base_entity/AspNetRoleClaims/AspNetUserTokens.cs @@ -0,0 +1,36 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System.ComponentModel; +#nullable disable + +namespace Densen.Models.ids +{ + + /// + /// 用户令牌 + /// + [JsonObject(MemberSerialization.OptIn), Table(DisableSyncStructure = true)] + public partial class AspNetUserTokens + { + + [DisplayName("用户ID")] + [JsonProperty, Column(StringLength = -2, IsPrimary = true, IsNullable = false)] + public string UserId { get; set; } + + [DisplayName("名称")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string Name { get; set; } + + [DisplayName("外部登录提供程序")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string LoginProvider { get; set; } + + [DisplayName("值")] + [JsonProperty, Column(StringLength = -2)] + public string Value { get; set; } + + [Navigate(nameof(UserId))] + public virtual AspNetUsers AspNetUsers { get; set; } + + } +} \ No newline at end of file diff --git a/Examples/base_entity/AspNetRoleClaims/AspNetUsers.cs b/Examples/base_entity/AspNetRoleClaims/AspNetUsers.cs new file mode 100644 index 00000000..48a0fc52 --- /dev/null +++ b/Examples/base_entity/AspNetRoleClaims/AspNetUsers.cs @@ -0,0 +1,149 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +#nullable disable + +namespace Densen.Models.ids +{ + + /// + /// 用户表 + /// + [JsonObject(MemberSerialization.OptIn), Table(DisableSyncStructure = true)] + public partial class AspNetUsers + { + + [DisplayName("用户ID")] + [JsonProperty, Column(StringLength = -2, IsPrimary = true, IsNullable = false)] + public string Id { get; set; } + + [JsonProperty, Column(StringLength = -2)] + [DisplayName("用户名")] + public string UserName { get; set; } + + [JsonProperty, Column(IsIgnore = true)] + [DisplayName("角色")] + public string RoleName { get => roleName ?? (AspNetUserRoless != null ? string.Join(",", AspNetUserRoless?.Select(a => a.RoleName ?? a.RoleId).ToList()) : ""); set => roleName = value; } + string roleName; + + [JsonProperty, Column(StringLength = -2)] + public string Email { get; set; } + + [DisplayName("电话")] + [JsonProperty, Column(StringLength = -2)] + public string PhoneNumber { get; set; } + + [DisplayName("自定义名称")] + [JsonProperty, Column(StringLength = -2)] + public string Name { get; set; } + + [DisplayName("自定义角色")] + [JsonProperty, Column(StringLength = -2)] + public string UserRole { get; set; } + + [DisplayName("密码哈希")] + [JsonProperty, Column(StringLength = -2)] + public string PasswordHash { get; set; } + + [DisplayName("电子邮件已确认")] + [JsonProperty] + public int EmailConfirmed { get; set; } + + [DisplayName("电话号码已确认")] + [JsonProperty] + public int PhoneNumberConfirmed { get; set; } + + [DisplayName("锁定结束")] + [JsonProperty, Column(StringLength = -2)] + public string LockoutEnd { get; set; } + + [DisplayName("启用双因素登录")] + [JsonProperty] + public int TwoFactorEnabled { get; set; } + + [DisplayName("并发票据")] + [JsonProperty, Column(StringLength = -2)] + public string ConcurrencyStamp { get; set; } + + [DisplayName("防伪印章")] + [JsonProperty, Column(StringLength = -2)] + public string SecurityStamp { get; set; } + + [DisplayName("标准化电子邮件")] + [JsonProperty, Column(StringLength = -2)] + public string NormalizedEmail { get; set; } + + [DisplayName("标准化用户名")] + [JsonProperty, Column(StringLength = -2)] + public string NormalizedUserName { get; set; } + + [DisplayName("启用锁定")] + [JsonProperty] + public int LockoutEnabled { get; set; } + + [DisplayName("国家")] + [JsonProperty, Column(StringLength = -2)] + public string Country { get; set; } + + [DisplayName("省")] + [JsonProperty, Column(StringLength = -2)] + public string Province { get; set; } + + [DisplayName("城市")] + [JsonProperty, Column(StringLength = -2)] + public string City { get; set; } + + [DisplayName("县")] + [JsonProperty, Column(StringLength = -2)] + public string County { get; set; } + + [DisplayName("邮编")] + [JsonProperty, Column(StringLength = -2)] + public string Zip { get; set; } + + [DisplayName("街道")] + [JsonProperty, Column(StringLength = -2)] + public string Street { get; set; } + + [DisplayName("税号")] + [JsonProperty, Column(StringLength = -2)] + public string TaxNumber { get; set; } + + [DisplayName("提供者")] + [JsonProperty, Column(StringLength = -2)] + public string provider { get; set; } + + [DisplayName("UUID")] + [JsonProperty, Column(StringLength = -2)] + public string UUID { get; set; } + + [DisplayName("生日")] + [JsonProperty, Column(StringLength = -2)] + public string DOB { get; set; } + + [DisplayName("访问失败次数")] + [JsonProperty] + public int AccessFailedCount { get; set; } + + //导航属性 + [Navigate(nameof(AspNetUserRoles.UserId))] + [DisplayName("角色表")] + public virtual List AspNetUserRoless { get; set; } + + [Navigate(nameof(AspNetUserClaims.UserId))] + [DisplayName("用户声明")] + public virtual List AspNetUserClaimss { get; set; } + + [Navigate(nameof(AspNetUserLogins.UserId))] + [DisplayName("用户登录")] + public virtual List AspNetUserLoginss { get; set; } + + [JsonProperty, Column(IsIgnore = true)] + [DisplayName("1st角色")] + public string RoleName1st { get => roleName1st ?? ((AspNetUserRoless != null && AspNetUserRoless.Any()) ? AspNetUserRoless?.Select(a => a.RoleName ?? a.RoleId ?? "").First() : ""); set => roleName1st = value; } + string roleName1st; + + } +} \ No newline at end of file diff --git a/Examples/base_entity/AspNetRoleClaims/DeviceCodes.cs b/Examples/base_entity/AspNetRoleClaims/DeviceCodes.cs new file mode 100644 index 00000000..c1b78372 --- /dev/null +++ b/Examples/base_entity/AspNetRoleClaims/DeviceCodes.cs @@ -0,0 +1,53 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +#nullable disable + +namespace Densen.Models.ids +{ + /// + /// 设备代码 + /// + [JsonObject(MemberSerialization.OptIn), Table(DisableSyncStructure = true)] + public partial class DeviceCodes + { + + [Display(Name = "用户代码")] + [JsonProperty, Column(StringLength = -2, IsPrimary = true, IsNullable = false)] + public string UserCode { get; set; } + + [Display(Name = "设备代码")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string DeviceCode { get; set; } + + [Display(Name = "主题编号")] + [JsonProperty, Column(StringLength = -2)] + public string SubjectId { get; set; } + + [Display(Name = "会话编号")] + [JsonProperty, Column(StringLength = -2)] + public string SessionId { get; set; } + + [Display(Name = "客户编号")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string ClientId { get; set; } + + [Display(Name = "描述")] + [JsonProperty, Column(StringLength = -2)] + public string Description { get; set; } + + [Display(Name = "创建时间")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string CreationTime { get; set; } + + [Display(Name = "到期")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string Expiration { get; set; } + + [DisplayName("数据")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string Data { get; set; } + + } +} \ No newline at end of file diff --git a/Examples/base_entity/AspNetRoleClaims/Keys.cs b/Examples/base_entity/AspNetRoleClaims/Keys.cs new file mode 100644 index 00000000..d6249989 --- /dev/null +++ b/Examples/base_entity/AspNetRoleClaims/Keys.cs @@ -0,0 +1,49 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System.ComponentModel; +#nullable disable + +namespace Densen.Models.ids +{ + + /// + /// 密钥 + /// + [JsonObject(MemberSerialization.OptIn), Table(DisableSyncStructure = true)] + public partial class Keys + { + + [DisplayName("ID")] + [JsonProperty, Column(StringLength = -2, IsPrimary = true, IsNullable = false)] + public string Id { get; set; } + + [DisplayName("版本")] + [JsonProperty] + public int Version { get; set; } + + [DisplayName("创建")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string Created { get; set; } + + [DisplayName("使用")] + [JsonProperty, Column(StringLength = -2)] + public string Use { get; set; } + + [DisplayName("算法")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string Algorithm { get; set; } + + [DisplayName("是X509证书")] + [JsonProperty] + public int IsX509Certificate { get; set; } + + [DisplayName("数据保护")] + [JsonProperty] + public int DataProtected { get; set; } + + [DisplayName("数据")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string Data { get; set; } + + } +} \ No newline at end of file diff --git a/Examples/base_entity/AspNetRoleClaims/PersistedGrants.cs b/Examples/base_entity/AspNetRoleClaims/PersistedGrants.cs new file mode 100644 index 00000000..86522eaf --- /dev/null +++ b/Examples/base_entity/AspNetRoleClaims/PersistedGrants.cs @@ -0,0 +1,57 @@ +using FreeSql.DataAnnotations; +using Newtonsoft.Json; +using System.ComponentModel; +#nullable disable + +namespace Densen.Models.ids +{ + + /// + /// 持久化保存 + /// + [JsonObject(MemberSerialization.OptIn), Table(DisableSyncStructure = true)] + public partial class PersistedGrants + { + + [DisplayName("键值")] + [JsonProperty, Column(StringLength = -2, IsPrimary = true, IsNullable = false)] + public string Key { get; set; } + + [DisplayName("类型")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string Type { get; set; } + + [DisplayName("主题编号")] + [JsonProperty, Column(StringLength = -2)] + public string SubjectId { get; set; } + + [DisplayName("会话编号")] + [JsonProperty, Column(StringLength = -2)] + public string SessionId { get; set; } + + [DisplayName("客户编号")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string ClientId { get; set; } + + [DisplayName("描述")] + [JsonProperty, Column(StringLength = -2)] + public string Description { get; set; } + + [DisplayName("创建时间")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string CreationTime { get; set; } + + [DisplayName("到期")] + [JsonProperty, Column(StringLength = -2)] + public string Expiration { get; set; } + + [DisplayName("消耗时间")] + [JsonProperty, Column(StringLength = -2)] + public string ConsumedTime { get; set; } + + [DisplayName("数据")] + [JsonProperty, Column(StringLength = -2, IsNullable = false)] + public string Data { get; set; } + + } +} \ No newline at end of file diff --git a/Examples/base_entity/AspNetRoleClaims/WebAppIdentityUser.cs b/Examples/base_entity/AspNetRoleClaims/WebAppIdentityUser.cs new file mode 100644 index 00000000..93a5bcdd --- /dev/null +++ b/Examples/base_entity/AspNetRoleClaims/WebAppIdentityUser.cs @@ -0,0 +1,53 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace Densen.Identity.Models +{ + + public class WebAppIdentityUser + { + + + /// + /// Full name + /// + [Display(Name = "全名")] + public string? Name { get; set; } + + /// + /// Birth Date + /// + [Display(Name = "生日")] + public DateTime? DOB { get; set; } + + [Display(Name = "识别码")] + public string? UUID { get; set; } + + [Display(Name = "外联")] + public string? provider { get; set; } + + [Display(Name = "税号")] + public string? TaxNumber { get; set; } + + [Display(Name = "街道地址")] + public string? Street { get; set; } + + [Display(Name = "邮编")] + public string? Zip { get; set; } + + [Display(Name = "县")] + public string? County { get; set; } + + [Display(Name = "城市")] + public string? City { get; set; } + + [Display(Name = "省份")] + public string? Province { get; set; } + + [Display(Name = "国家")] + public string? Country { get; set; } + + [Display(Name = "类型")] + public string? UserRole { get; set; } + } +} \ No newline at end of file diff --git a/Examples/base_entity/AspNetRoleClaims/ids_api.db b/Examples/base_entity/AspNetRoleClaims/ids_api.db new file mode 100644 index 0000000000000000000000000000000000000000..a45d6fa32d61ff3f08186c00d17d207548783f35 GIT binary patch literal 172032 zcmeIbTdeF@dYHF&pYC&;K4*_4_Z&;((HxzYGSlkei1$kijTsh;tYVR@3omtZ#x(E6 zDi+BiSyw{{xx3tV^|MH06)YD@{l}44~8uZ2@=Byk{2Nk zWCU4N`|Pu8@3VLJmZnGOnO=pn>yYd6^IzY;*3WfeaTz@|u7c-bR?MC1IdSsklhf0a z?>>Kia&nS_zh4G_7oVR42X9`Sfd5aAj&D0mPrf~9zO_$$_Q(4)f9~v$pZ@Jf|L)1J zKO`Uh?)`uE@Jnz0oBJQ#`%CxUKK;$p=4tabF`xhN@BGyLX9jY55~qH!DHjQVYCFp+ zJDl5mnYV+=DuY7JqBt#W?0U#gfB)p{!7~Io{Q*%qZW3I^3yBlY%j@S~7Icv}#pfnp zQ^n^mu1CLk{>>+kpM%c}*?;j|Zku95)StII=JU3ts?UW^+c0$=gg<}LRgTmGBeHnU_Q4iTZ(Wu}5 z+Ls>et@?w-!K~e&DC4pU{6^uVReA07?W+d37JJEG3APti`<5p4TGk`@7fs=~gQ~-6nC-8fH-3sW66gnFlTL#SoR^&5ioB3s3NP}~q@I-B-#?%o(@ zR7DU}H)I;e`3<2$woI#6zWzv8A-*vfG`>{~x(m07DsGasZwC7t*$tWYQMb@)@4M_t zybJtKNF>gkIJrUYW#-#b9KwYx4dVj1^xJ(&*D1?&R`^Y)oZN6BBk-2MxowTgncoaJ z1qlk!#kw^~cao*Stp+`cy@R&qI+Gl)$_g>v_p(2sTx#acvSlTvAkBFv_sIIMB0oh4 z?}46UDFGV<{-G+p&Jj3X>i#FS=cC4SJZvZ*eDuA0hxYva(}Np6Pj~1L9UZ=TQ+vMX zH60BRuJq%tJK!UESB3@`{`FI9=q(9=!EQ7D9?P4bj^$923oM6|w>}!4K6u73ryq9? zSZrIAv^YBNw3JQI_sfdyje&1mMRjAEODFhB=BIkYTLj(U7lHTimtOU%mvO}?fQbCY z{b%1}Zgc!MUdP6648C_hqW+n)C*a`p>|dRLfA9kdKmw2eBmfCO0+0YC00}?>kN_kA z2|xlrmIR)k-uv(wj^YH0qYOro6hYXrUmAz?Y3AGLxADiIT&HLM>k0S=Kac<<00}?> zkN_kA2|xmn03-kjKmw2eB=BQQ;H&pOe019+z<&Mz!PEczkN_kA2|xmn03`6EB!E45%X;UX6AX6(ipD}DU{D7kNrFRI zm*SAnXF1QKX`dzn9V5~GA9nwcg>)#EWE=t^2-ihO0u2x+#2CbL(a>dmm+}Z##|V&x zK(V(DSptIM9LJ*&JoHI~WJ4BV34%rlmJ1jMr~Qy-bqohta1?vL_BBpnixMHL3kj` z{uex!A?m;S##`3czkWhv4(Mf-K-toJTPTPGcM>CeVNljAb4aOOVg7x}v_% zOq{-DJ$rV72c8qMWQdRy4z34E2(CwS2!jzA>fs#eFd^^H{j)Ef{m$9<&d497iJ@#r01|)%AOT1K5`Y9C0Z0H6fCL}`NZ?07;G6fX)4R+k zJlH3^%PhkEeZsrU9lW(qc$XQ2H}?teGEZ=CpYSfT18;oep7rQ1GXYPY{@*8$-}r-* zH~!$s-+z1lrS~8G`-lJh!GCeze(PKJ{@)*kHK0sL;Lno4$6q=9nss!+uYUu49)3h= z*2%+%CyyRtTu3mU>mV4za0rQ^A;MCqk6;0dI%wcA9*(`5YO8{>`tJVg+g>&|MZ^5= z{_ER9N4q_S@A2Rx^Zdw(_D7;bMWi*3S#(M@=iS}Bi3ycIVe5H+TX+2SWbUt3bWRGs zK)Vwu%e2?^{tDW!eg%#A z_vvk_4j9uYyUR|8Pz0)~0bcE)*&hx&8jX|qh$059dap)kwH`4vhXbWur@a6pDWEtg z6PVS-Xcu7_&P80;Cn+WjY0P7RwjZO9J`owkkpxTQ4&o4dF?awZ5Dbp^A?I+Y$NIPn zq!BonKn7LKbHP{W`v{9sE<#fd#h@5YF*viIJT6e|5*c=h?55DykaagGTVU~QENGO2 z4-`(ud4fol@ua<}w#0bS^Ln)&m8e-~-Cj1@jl8`swq3VeRD`CwRPVzN1#8q0hnisW zZK12Q4YAo#^!{KdcGYgz5OmhZTn2m)(g73NWI%a{O9uf0tWAP>cmn4f50v3!^x-EW z^9j#oIhsT`mjtpf0ET5)49wb7wC52tM^RMhk{nHYG{T`isAUuj=GwT$ZW9gVCRdc#x(ZK2<{6s1mdd087-^;*pY&B0?G z22B5h)eVG1J#Ykyk1!PN24P52m`ej~KSm#XA~J`fNse#;Efn+jUo7JIA!wLj#Q`)* z0%bUq3~&@>fLB97djt-EW5EIfLm{3|GcN0Z^#kT5GU5^$af$4v(ASV@7Sj_~W2H&7 z8|zJ{TCCWpUo%z-A2QCyi|bgdSq0sRHd(K(6=a7rI#{<`TVqjLueutjWyVNrij+=T zB5zPMW7c|B$CA`qgE6#TUyv9dv_%|LiqIwYwTvWyBjZ4eq8ZEyP>Kc1Axo6_7`^|A z$S{V&{D317)WyJZQi$US8`1>AaU2UO77jc;2OK2fQJw>utOH=WE{nJUNC+GmijpWB zg2kotTK3A9S(mz@!+(f5Ai;o$f6jw~D zVp<>T43tr94Du0$Q_EFWaGL_uvYuM!B~9(q1mDp+YHer`)VL{%y-t0sYgP}my^wMp z8rYg(LF)uwh6C;m6wCE+oJLuXz<{NqpKSME$@vsmhyqC4?mDjR>TYJ?oZwh@48Q+|(-60_o zi*+ll#%$v9&1HvF(M3xbE#Id-OTpVcqBfvg+cbHf+Uf?YDMCmYU}BM3DaP-E*C)sF!jhIvov-+7y~i(d?TP zQy28nNW}$-uoTe>DAvKT&_f)L0}dMe*cjmeMTDR{)OCE1BRKM)@yEY3rvZQ$lHeXdf*S+EVJHV~Dws!uMO*>{E2jhjZkj}h0ILBn$^yz<$bz;Uus(@n z9OmQLVR_TpuW??`JFInH(7Qe6HF_OE#P2nL68Xc%k2aP|jz40~c>qkAd_rT|?Gum-*Fhk&(j&?P~9CS)-O zWdfSv_U`Ug#}>cR=f$sddT)q(jifj;Yu&P+cF7>X6RFC*56@SiZ{JLN7 znx1HFT*uKo##y6kibtef!{toeXKnazWVIp zqrW$=F`PuzXb$DUk3V@57s1;eYEm8La2%_N6xcu({1_PgvJ+*VW7G#E^8v|y8wEf0 zqzJ5xqclz<-2ktA5W;$k?dth-oQQ(3kGgza{H ze$*|J*c!Flc`#^N-IVV3cFP4-+IE%OLMUR2#Mr%}Rg9JeqR+-Som-_}$#yVwmq9nJ zRE`zIY^Q1+-WN5twGDQZi zp0QPJwbldIsM#x=2R{X^jlF2&x&scG$S!3xyHjVU#E9*pc0*^t`q`Z zH(hd@k5anMtu{M#2Yzk7+pSyuK#`(C>~v)&Tg>{+*q$!Q-UuT$;O!82miJdI8f~-O z2!gpT;>nb3EOwpNLJ1R zY&0H3e6WiYWQ^$3N!l#eG~a0?N+vX|H0G6ZR^RqV&NA68=|Qc7DoGKR{X(HVDQLA? z5wYS!V^j0GLX>BqFhgeQ8Iw^cq28Rw=i#Wf!dA>yYNJI_^_5nzUguatl$RVg3uI0#HKn)GZQtDp z=z8Lm)Bd>GSR1i84yaG9~+s zc3DGls}$Ijlsd!+p*wjKw90TTD!axARgevBjahZB@qEvSGr7GRBBM#yn(B>U=T@G; z(j9V4af;q*b!PQ+Clh&F2XA`mRj5`a9fu`GGmo%(Q#F!D^W4m~p3-+a@p9CqR8?x* z;{@Y_)`a3WgIvP!NrUZ7atz5@Ef>7iL-5L0GeLD@>xuEIro^LhLATSzfU+06VOLpC zn?rlJCWeD?d+8<0Y~5duwhOa{JKN?^!CFbJ95jP2D`l(oN}MHgrWECT8R&!Y#_QO+ zRx5DU@7a?&X~arrIZhG292TZ0P#b5+&D=WeCbONts?F)#kXrs=Wel`x6s;S4M8*t9 z>0#Pm^_QzUBAA=?&>t?iej6QCWLr~P9ND$Fo#Tqler?=j=c^s(m(G;sTZCPsc^g|A zxW^91)YbrR01`$9hk@4{EET(L&caxk$%bpXdcV0#hl|Ce)uNJa;Kp7c8xz_nnzJEC z$RlSb^@FiX>3vk%V#~VSYi*n3QUbrjuhskIsuCNis*wZQ-);?aF%DN|y_HBf#Wf4V6I?>~mu`TOf z*Py*_Us-zn1>5#&0sgUh3>|YWTK9Z@;I?T zqGrDf-UUCN4YQuIsCO3X6z$oTwV3v3Bb}qjP8oCUh%ypk72+6M^F5crxfFF9lCSmT zA!p-#vB5Ss7D+00!?ZDy7aHm&SyBzV-Ap_AC}=tb%}ADzV(aRnr1YG#Vld&vXQe5nxoFT3gx_(_4;;E4f;Z5Em37j zRi?i4V#hZdX%izGB#HmOm8rm zk%TH)DN)l}*ir;{EvGdldYYZ`9@CWlRaQq>BwFc)weam$f{?bhihW_(WCJf<^c#sf z^f0}u223T)aJ=1eXT6PXRr8z=kj5O``|OxkHateNp-OcT1kTbJ|7jLbEW_|xG?r;r*oq}D2U<%J4Z9W{kSss$M7y<(P|0*M*-_EdNCvYiBO*=a`bmbGbRgjD zrsu7)l=D}V5GV7UUAS{lO|W9#DAJkGuo|*Wt#Ym_l3ioyH{=G>%G6@ug$*rcg^|Z@ z`UNKf|2yB>wa7P|no_w%PR4%WlO*5W%mkOkQh7KMyK{p!DYG^QCg}c=w+6=+l;UE`I<2 z@LznMiU)Op1Rw!O01|)%Ab~G7fd_y2qbHc9edmNAPX5+Cye5Jz59%b&l7z_DabB#U zV8e(yi-UcP>C2RV^H)TyUYBrAU@`D;2gisk$FQgbx=8{>(DrKoU^PZSrPA?D$Y{d%lzOj?^6OBQlof{!3B&Gxf;$$pf@JeDXB)Y zG$jFT6K9td1E-wJevnpiwf(k`#Ng=S`5GL1j^Q5=*asBYO5^;Io0mZ}2>L58xui(E0jDnx z&*_LGWiYDg37gkqwP+LVWPr|u9UjyrqBcvJc-H8RI$+J1=gYi}q5bJ};#M1?f%*En z%d57B=ruOT=HoOG8VzhcqLxO`G}}`yudTJ2psx5)2V<$iF0vFKN~`f^xFQ)h)iB3j z&ozYB`9w^tox=1tR7^)$RK^t@rHxsCxI$N9FKqQH-OWe4&K$h6UT=H4>~x8_5jIlO z9LTGX>w7w*cHMf5bl1IQY>#z=FmSHRs%c}pwrZjw@0*?T=t=>d5!qPQYjha&va4zY|oMOjkHPwY0++_=q+L})xY5>i|P51!2GZD)!shuC`3=0aYl#{GO24U1*X&4;^L zS6Fkr&{XaEfL?PYlFzk8oiW#ewxwE*uYf01XkyqT5X%+E7+&oE9 z1@nZlz%IcyK#FgZfksSbR0bAzG4KX?DNoxDu~h@EhR!Daspl|OBZ>nSSXb@%Og*Wj z+*ZMB-G|Xu8l*J^OOsY-vQr3d&IsP7nUOd;oADb|iP@otj(Rx3tJ4r~F06$*qse7& z&?HoK*zSv>xa+!x-qK2xGjy=8O|4{n;7Gm%G%{$h&}NSju3Jm2od@vcj`GplZ;k&^Fd*=VqMGVD6* zQ9}uW&2UK~CZ*LD_5Ns4MxL;?dSR34)Y=v%hE|g_k`1DOXN1OHcRT^xStx!hw~?*Q zto=p0G!(GyNoeL1CCcr<8sZ%fSr2?>w^H+&kvmmSSW}rD4*dCG>bFGGpD;LPv0R(i z<)k(5v-4iHX=#(s zu;q?ETW%VYPJ?Z=3`f)JY`6$H1Dj<+%Cpi==$p9;HlJ!|s#A*uBf+JzDJ=37Y>s5+ zq81M4QyyQmgSJ{_O(kwDT9hqFN~@Y`^+`_&B-2=8#?n$_G|g`(JuXWbvlB|1SdKf}!jkK3 zv6`wf!7T}4z=m~`AFo|`2=+ygr^B(FY*Vtgq7hrvu*Gx-Hue~M<59Mrko=rRqGGq< zyHW=cxAWPcWzV@zE*ScX8*W!Nwe5|Y6JN6Zjj|P6UYl6$T%vDG8}tmZ8Y`@t`!yx^ zH)ccd6^&kQBU=^y_I8;uqM^ibJnoFL9X+9^HLfg-ZEh1ZKGHgytW;_SRU0YbK_V8( zOldZ3V;p6MTU~36tftMmJi2xT%bX9!XyVu8W^7?QelC<0vcx0-Yzea7^kN_m`!xDhw{~wkh%nu1b0+0YC00}?>kN_kA2|xmn03-kj zeEtc*@&D)FMo>dY01|)%AOT1K5`Y9C0Z0H6fCL}`NZ^Mh0LTA7EJ2tb5`Y9C0Z0H6 zfCL}`NB|Om1Rw!O022886S#Q)-{)Ubs39Z(2|xmn03-kjKmw2eBmfCO0+0YC015nQ z2|PLb_a|qkzj^ZXe>(fGp8V6NfBVtDd-CfK$w$9?|DQel(p%5p{5SXh(!IA&fAh3? z+WgaA;fs+E(ApTt=}DaW!KPd!aTVBL2chh6Ztu6x2`Z}$3N?%3w6wA7AwT{7ld}iU z5ajd+MCG_ia2YQoPCPHKpMP1s{o?sIpFDmJJ}+ed#dEoBiVabJ z-tL&s+m@<67dmaj)Ois8{6$weQt$j?FP?XGS>yH5b446I=Pk1%x54!^v2A|qrPzI0 z_M%O32xPvLdl7k%Vs7)`A|71xN?hMbmN!Hmt0ldz){&m2eW8HV(M7q@K4|*Q7cWEK zd#;O;sEchuG>+kvfXkl9d(S)V=XFsP0YQN`1imgldHi1Y>HTN#zkfP97~rK1%V4n# zQZKl6dUgf>wa9O#&OG=Q$oby)PoBJPR6R?AW20W4KfNOLrBN@V|1?HD&i$!I-6#ID zG3upSFO9knDD4Xct{U}a=uJjFWcx&;e)#tNXTA4tYnT_iY59lEv_QMO7VzZzU;EO7 zeWm!p;!rEDMPEC8`>Oq}#a^0E3APt4bf;(x7t*Ztvn@*9v} zY_Rs4N4>DgfdSZW?Pk9SywgR@QNj2m0{hHWllev5HE41iYg9ccn>kj?m z@>e%~`^03|E(TD3-zT z9X`Bjfuop9L+rivKHoK6uAAdZ-W#lP8GlXC1(qM5=5WpQH`jUU;r(awySEwYk_NEX z(aEE~`jxj1X8UXBP35x7aMZad?_V|BQKCz;eQNu;lIsS8wZZ-I!c<2Mq28(85Nd%P zx^4*0i)1^7|xqD-rQ58W@-H>S<=Qo53*)pwOIqM@`1+a7D4e7y-i>nxP z7jB3;h$?Q%v~LFc8`%w+_EERcYG=jVN#b4Le?lU0?!?IraxXLAmf{c&c9sm|0{G zG2QpFKcQS|=FPHYC8n>O`H}TsMShA9-UB_yQUW#z{Db{p=Lj4xb^nvv^HF0u9yXK@ zKKkChLwo-I>A?-3r#p0rjt<|vsXbrxnvRADSNieS9q^I7D?@_||N5yl^p*s`V7D26 zkLArz$8spi1(w6fTOSQiA3S52(~mm`EVeC5S{$ACI?5*4IyEb{HwM0O71fPtE}h^j znV;$nZxM8ZUj*L6UwYN6Ud9!p03z}m_n&=_xy|w4cpV$NG58)Bl|S5%%%42`yC+{c z@lGE8pAY}R{oi^Ry!j9Bci#Nvd%t&&edBlEpickiQ|IJgop@*e`0SUS{>>+U@Z=ZY z#@_zdCnx*AJAbx6|KQno-aY;3YlpG0JhYE)O7>-s@F?^bURpwK*To?i!rqqU#eNv~ z;wU39&x=cmFW&p;q%${zes!qTkE^!h>hu z0HuHTpuvT!miN;HM=ks7H(vEh>hmid<=GeZ(vM%HeevF3{_2BgzW}cI=y1h@AHRON zpT7$DGR>!4ln@>_d1*l-s|w^Z`I*^aQ||K z;<6m)!C(CZ9j;`&uETlcu@1?z^Q!gL1BN}Fy`Md@^}!fF_ws^QEA*Ar$Cos&SpW&tA`@;+Bm%%@KONlR2++g_2$YaZY|L6bQ`Fu)tbj#bD#LQ+vdeo0S zKY#Y}%CAk5oks)7cbUyP82`|*JL+y;>!=^!;I2j8VXo`S6x@YwNB4)zdiSm8FRrQs z0?y6z@?L!F6xzAiqbBzwnL_){JNKX6Wg7IQHb>K-=OKUo`}$8G=39Q_FJ80ozCs)s z_;C8pZT3CH-qF1Kw6ER6Z=iX_NG~sNn~h$|eD4M^SLQVjVt%AEV1E(~_6_MrQY$|E znNOO7yY!IfIF2gCA>b>I|IT?|l^@AD5BcfuqhCI_kKg#2YnAIf{!)?i z^Pjq{dYwmK*000)r+A2qXfT6vF-*GVC@xae<1$a2?XgQa8hX6E0o^#kblmu_RM!iI zuh!SAY6DMlp}}6qPp!M>GJn(#<>ch_uft`L%hj4I?&IZc_p;vpNLugJWs#5G|HTK- zFzoc><5B0nQXblBy~-}Nxd?ghwsv%p0JNm%&-b_Di!R=^+I=2(bIm`*U9HzI6TSyV zOu{eSe>T8w8!^4E>cvpAGLc{@I`_JBe=QOy`=P)}DD((LN7q4CLBKBPPAD0|`I^kN_kA2|xmn03-kjKmw4! zPYeO&@jc7JxR78x*Fi9b;Sdr-LxiPJAHf0^bM^J}B5t7Dmg!3o{ z!D)xMHL3nsbD-VD$iX#b@ z#vQ~VNE{*Yz(rhw!4W^?91itZA9txc3A+!3`Gn`P98DseOMs3XEpl2caZj34gcRzLG69?S&jeU`~SbVZV;9n5`Y9C0Z0H6fCL}` zNB|Om1Rw!O;EO{5zW@J=V{2GaNB|Om1Rw!O01|)%AOT1K5`Y9CfiErrIR5|Q+8&l1 z5`Y9C0Z0H6fCL}`NB|Om1Rw!O;EO|GKmLDk_IoF1|IgX~a`r!-{qwWmJNvh1fAGaA zKP)LE00}?>kN_kA2|xmn03-kjKmw2eB=C7B@bKO{r#eQW56%w=^#1t)j=pt%fT3^h z4=h8}?>)Kq^;5&@iu(TSjfeN1J>u({+=lD_pLZ)m{U8BI01|)%AOT1K5`Y9C0Z0H6 zfCM0cAD#dl|Nrm|p#(?(5`Y9C0Z0H6fCL}`NB|Om1Rw!O;PXykKmLFGG&(u^{j=XW z`;D{josnl>disY?|H;$e0)g-Y2|xmn03-kjKmw2eBmfCO0+0YC015ob2z>LNbxLCn z?gl=Npbmo~B#q$+=TQuT(-`MaEP?rK@OYo_PWvS86W(Qm`-gW;_~5Py@831yTX#+P z=3NusyKBNXzH!fbbQe5_@&DQI!t!arU2{ZT@5?hN&R| zNB|Om1Rw!O01|)%AOT1K5`Y9CfiE6`vwQEJ>L~tQzT5q_(9s^BpJNy2kM`#lN?x2l zJU=Hc&L5ngzsi6A{QOn^w|?s0H_m^~f05(OeaPV_{TCtke)`^fr>1C_-`#)Vdo|wp z^1W|7dKGj~44CFI9RGjuDkv;5BmfCO0+0YC00}?>kN_kA2|xmnz-K~WKVJWF8ULSr z`7kN_kA2|xmn03-kjKmwmr0`UERpHss?wIBgV01|)%AOT1K z5`Y9C0Z0H6fCM0c&yc`={Qt(;zdbqoBk%=3kN_kA2|xmn03-kjKmw2eBmfCO0+0YC z@Z(M3OZUEdTEr%j1jn|Fi$_<6S(cJtP1LKmw2eBmfCO0+0YC00}?> zkN_kA3EWEH%~#`pxcYx9Bp3k+Kmw2eBmfCO0+0YC00}?>kN_kA3H&$_c!r}mfuJ~o zW6v@C1A_j5!d{L4|Nf6tNuaKf03-kjKmw2eBmfCO0+0YC00}?>kibte0SkMCaUsEY zu7h9Y#zgcsN!|oLyE7oN_MvL0ZMt_S-@dgCl2IO|l~1IaQpc zwwL+AtMUKe{YmBq%LWNR0+0YC00}?>kN_kA2|xmn03-kj{8$k9kMB0{$4C^#YYZ-6 zl*rX^M#4!^s8dpnW@$>|#n;FGPeAcc-}(kZx>0|AY@YQDz zAN{>~jo~D!Msq07i6l?rBFnNhsg80um`@fd^y1kulzEO(ACSxkB=>EUKyiw|UcO33 zH*ks;!g`DC>iKk>h=Q<@($27tv^Om_jHsO@ZCb{FCssqPp2jQ|@hfr4)`|Wkuk$@i zqO{Ir86|`yO`H8jl-P+EXmY%X@DbypSWgRT8xD1haV3%sTFHro?RI^B)Gds2m zNfypV2#1KKZPL_G)@I#6w_1as)f1ZoYgSFLxw2_cY0;GRs97u6tnHKXw%k!(BE=ifXvEW})032eY1<_ZQ>Fs>9+LTh&%;J#dYh zy~26KXKG_F+PLn3Lng9I8O`q0*(ot%yQtmJ85#>4>>pjBl>ib zHp?~5cN&S32~8`Fd8M4yxBZc`Om<6pQ0t&dQiNr{P-ssITCG+@toYE_)V!_`8*6zcQ*pMo;c;SKW=swb8H=q zTV^`!mHBuqR*7h;ykgjBfO7fJGjgrM6vaa@dRPyjvC|+et%b%H%UQ8hBCf3W7TmBEHT_01>I`?j zut0r{vKH8&*R=+%!E8KghxmFX34EpCJ>IGK?UX2^ge+6C-)NUL6t_x&O-ZRkj1an$ zH$kfm*P^m(j8FyH(AJn$=NixVj5w3qyCE`~bgil02zGAe2`t?q#}udNtyX7NPj@nr zxAktR^(s`Wl8(a?qnSroy{Q_>qj_#-TTkh`op?FwQmQJo?Qw$fL2E+sn?WvN_@u#h zCOL*=t(L3qQo$=*%>>nrttZB-ni7x31>H^;1Ik|PhFxVnZ4T|>nivko?WLC}vvq$t z+Aho*?rfVw1#2a>a?lLAtdyo6L6psy3%{Lu&bhl`+t&QM7LG5g9WarH5&M)nBgah+uBkLw~s7 z`fYSnk!?+Fab(xxc8)7H`?YbCov(JBUpiBkZxMEl=51_g;2t|1Q(GhSIbmdQn2zI1 z#crFkFji)=;hL`AZ|>6JVlip8sH7XXu@}h3gf@!iY{(Jv$k|E#VC+(QACy<11KQti4RbLLS7yDHNLWKFshQuCdqy9K>NqobMHz&9)oO(R{|?EV1ZlY%&qswMN#rxS^co4afD2ajvb`?l#DZB)}`VyJMuF zu^P|JfSZZktd3>t5HOy>4Gwdi@34_G$vL9uf_D zUerA=rFqHnn`u3?#?*AqWEIv}5Q&BE#*t*Aj*ap-u|T3`zsnNDcs9&>%A(#`s8h6O zTh?OQqm6WqB0FWwwIj+%gjI-RY|Zyv2Io@LZAiY>lZTv*_r(U=+*l;3*bURhNM2~D zn`B8f>~=HlS|)?!>3iDom*a?FHsg_F~^&ES*L8Dv7pl3Ty1 zt!YM6Sj-aUE*m-9pgHQSt5D8sS+8#w)u1m_))G~gRAq|1Nn`qw?|S%Xpp!rF&7H~ zj{m9{-E-nbDh;pPLfEi?rz(nq1{Ews0 zG3En|`vAqijiX?~nWbJE|BEAKFskVZo7ZBsXcO&ZfX;Z@LONO($6G?g_HmYFrn`;N zXFAJjEq2iDq5?O~3MqIg9M0L@QW=zXI&89wSrV~_7GtT9d2NRH(tPbl zLEknD#bFxGRveC7N^Ge*Icc}!F-s0(a=5_T3K$FKlisl1aHoll$%|d;a~7GVM!42n zi8`|7Uc)X|d^R@gPHnzTgJFVo5zJ_G%^gL0IzQnN#p&@=xw6J|Jq+1qzYRLX14kug zlF`XBURu;#&#>*1-Ke}g?qlt)wTxB+QX}SK%R!eDC3md0;nBG-<#jn(2;-i~_oEq+ ztip-il(JHDC%f3I7NHRiK=-Ak>g!>Y>^8Hgq@_W_=~F^Mg^QY+NjyGjVkNP5`f;J* zNN>5qqv4`9?rUqTrQ*#XZq_PGN6BEsOPS7+yxN^jqFf;;U9)0jQZ|Y;7TUCvx4aFV zR|}VLI#o=vEt{|J%Go%U#4z^sCOJ@|Nh*Tm8%2?Nrh+sgm0UFgX^S>zO}X2n@kA$l zz9v;R-N3Ymo;Tbv_@o}tIGkn!X)5E3on^8 z+nYh?%$OV<5Zl4lOYEwm(Gki;Ykyls{Gv|F)0N%I=k0i@B4{>_h3?3iQNt0s5NDZ* zf+0OiXUJsd6n2nTm6u0US3=pvZZ}#f6zwtFE-TaZWmvKWW6c_Mrp3{Gjxx(Us@h8- zt*d2ou98NhKA)_lzNvEgO504r`P^T2$z^BW>e7V2LOG_I(<`)L<`t_Ty+IFkmVsp> z#bDVIT#E2jq{kQJ3}0hD1G=G1Ja&0(s)BLhR*n3PtWi9hZh2x9^J6=~IErypeUT3A znNTT0H1%X>iEgasCY;o&)u!9o%>t)O_DX#qFn%(dBE8kT&~|l9MI)@a9UHvcw&umo zsios#!%&iK6phCEHqe!sl4N|j6N^z9W%EhtEy5OMN(EOjXkDbhpnjQj;+gKCz5cM< zjC|WBO{|IejiMLm%)nZ=dR!^;Rcppcqo%0kT*R%$GT!Vb{n^l2&Co8>^|}LR2FAYy zYRGA9#AbIiL{fZ>#JjR*$NdR5&{O z@uS^3730K7gSyWpbZE)8(cEnMXfO)FgooW~WvtOk3=v0a1eoO6+FR2gnpA=|M6V;; z7B+14lAYsK!>pJrkQD1}R!E^nw$xOB+Zm3VlBe`YIH=8t#!GtSvFf|d| zj<73PGaSsf%aPR{y7YR-_gfPdoyzNRPp{3wNm4e#CN3kL4b|lpcV{?sdppVWUfx)# zO>;3*6+`NDdW+?(N9;7e?r59D)13{nnpEv{Frx83mJFt|#bDU)qFbZQHn6-%*`-Ey zf+(0qm6(lc)VS|Pd`Pr5;Hl+ulSuU$!${VXvpXI790zdf6L=@xtVG9o*kC-3du#+wpKE8_hM^@zp7> zn$>30T}+`wI&|rd%?6S4K?)DaDb5|Sm z9317skU@==Uo7*EuaH8vL_Nl6uJUqjW{B(Q)o_vOO3|(t+KN<0Dq34O*tXl>+4Njs zS=U~WZkc7)h+=FNSz)RyWGq@PC*f2CQtcfRPi)`HTdkR*b9q<~DhZuszO1 zuBuNEPF&0QVnFUBaF?wX)2ZckePQa)P`z!DJ6;G0cB-s2OX0D_q%6aRuat4$Y|;77 zjJv*>M23Us(~aEQVTvYz2`CX|z{uXl8&+V~Nibd&%Ehv?NVfK>(QJ0w{$kMQTehhQ z%vza~9mm@m#iE~8)rhhsj)->Mnu=9|>nkc%*_%-zmS7~@E$C58c1)vz^p$R3?uo3j zZAyy-Ow-qGzML-7GGVvDj2BgF=U8|P{9zp_;03-kjKmw2eBmfCO0+0YC00}?>kibtI qfs5b&|HKsx76=l61Rw!O01|)%AOT1K5`Y9C0Z0H6fCOF<`2PWcrjKF( literal 0 HcmV?d00001 diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 2cf63e12..a77ef7d1 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -1,4 +1,5 @@ -using FreeSql; +using Densen.Models.ids; +using FreeSql; using FreeSql.DataAnnotations; using FreeSql.Extensions; using FreeSql.Internal; @@ -524,17 +525,18 @@ namespace base_entity .UseConnectionString(FreeSql.DataType.Sqlite, "data source=:memory:") + .UseConnectionString(DataType.Sqlite, "data source=C:\\Users\\28810\\Desktop\\github\\FreeSql\\Examples\\base_entity\\AspNetRoleClaims\\ids_api.db") //.UseConnectionString(DataType.Sqlite, "data source=db1.db;attachs=db2.db") //.UseSlave("data source=test1.db", "data source=test2.db", "data source=test3.db", "data source=test4.db") //.UseSlaveWeight(10, 1, 1, 5) - .UseConnectionString(FreeSql.DataType.Firebird, @"database=localhost:D:\fbdata\EXAMPLES.fdb;user=sysdba;password=123456;max pool size=5") + //.UseConnectionString(FreeSql.DataType.Firebird, @"database=localhost:D:\fbdata\EXAMPLES.fdb;user=sysdba;password=123456;max pool size=5") //.UseQuoteSqlName(false) //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;min pool size=1;Max pool size=2") - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3;TrustServerCertificate=true") + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3;TrustServerCertificate=true") //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=toc;Pooling=true;Maximum Pool Size=2") @@ -570,6 +572,11 @@ namespace base_entity #endregion fsql.UseJsonMap(); + var dywhere = new DynamicFilterInfo { Field = "AspNetRoless.Name", Operator = DynamicFilterOperator.Equal, Value = "Admin" }; + var method = typeof(ISelect).GetMethod("WhereDynamicFilter"); + var users4 = fsql.Select().IncludeByPropertyName("AspNetUserRoless", then => then.WhereDynamicFilter(dywhere)).ToList(); + + var type = typeof(Student); var sw111 = fsql.Queryable() diff --git a/Examples/base_entity/base_entity.xml b/Examples/base_entity/base_entity.xml index aa997a23..f7603c7f 100644 --- a/Examples/base_entity/base_entity.xml +++ b/Examples/base_entity/base_entity.xml @@ -4,6 +4,77 @@ base_entity + + + 角色声明 + + + + + 角色定义 + + + + + 用户声明 + + + + + 用户 + + + + + 用户登录 + + + + + 用户 + + + + + 角色表 + 存储向哪些用户分配哪些角色 + + + + + 用户表 + + + + + 用户令牌 + + + + + 设备代码 + + + + + 密钥 + + + + + 持久化保存 + + + + + Full name + + + + + Birth Date + + 组名 diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 8f8d1400..b9189798 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -561,6 +561,14 @@ namespace FreeSql.Internal.CommonProvider { var methodParameterTypes = node.Method.GetParameters().Select(a => a.ParameterType).ToArray(); var method = _replaceExp.Type.GetMethod(node.Method.Name, methodParameterTypes); + if (method == null && _replaceExp.Type.IsInterface) + { + foreach (var baseInterface in _replaceExp.Type.GetInterfaces()) + { + method = baseInterface.GetMethod(node.Method.Name, methodParameterTypes); + if (method != null) break; + } + } if (node.Object?.NodeType == ExpressionType.Parameter && node.Object == oldParameter) return Expression.Call(_replaceExp, method, node.Arguments); return Expression.Call(Visit(node.Object), method, node.Arguments);