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 00000000..a45d6fa3 Binary files /dev/null and b/Examples/base_entity/AspNetRoleClaims/ids_api.db differ 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);