From 3ebc01f88d9889ee078675bdb898bc7a7beea978 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 4 Jul 2019 19:46:51 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=20true=20&&=20...=20=E8=A7=A3=E6=9E=90=E7=9A=84?= =?UTF-8?q?=E5=A4=84=E7=90=86=EF=BC=9B=20-=20=E4=BC=98=E5=8C=96=20Navigate?= =?UTF-8?q?=20=E6=8C=87=E5=AE=9A=E8=81=94=E5=90=88=E9=94=AE=E5=85=B3?= =?UTF-8?q?=E7=B3=BB=E6=97=B6=EF=BC=8C=E5=AF=B9=E5=B1=9E=E6=80=A7=E9=A1=BA?= =?UTF-8?q?=E5=BA=8F=E7=9A=84=E8=A6=81=E6=B1=82=EF=BC=8C=E5=BD=93=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E4=B8=8D=E4=B8=80=E6=A0=B7=E3=80=81=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E4=B8=80=E6=A0=B7=E6=97=B6=E6=97=A0=E9=A1=BB=E6=8C=87=E6=98=8E?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E7=9A=84=E9=A1=BA=E5=BA=8F=EF=BC=8C=E5=A6=82?= =?UTF-8?q?=EF=BC=9A[Navigate("MemberId,=20ShopId")]=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Extensions.LazyLoading.csproj | 2 +- FreeSql.DbContext/FreeSql.DbContext.csproj | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- .../FreeSql.Tests/FreeSql.Tests.csproj | 1 - .../Other/CustomerCheckupGroup.cs | 89 +++++++++++++++ .../FreeSql.Tests/Other/CustomerMember.cs | 108 ++++++++++++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest1.cs | 8 ++ FreeSql/FreeSql.csproj | 2 +- FreeSql/Internal/CommonExpression.cs | 55 ++++----- FreeSql/Internal/UtilsExpressionTree.cs | 26 +++++ .../FreeSql.Provider.MySql.csproj | 2 +- .../FreeSql.Provider.MySqlConnector.csproj | 2 +- .../FreeSql.Provider.Oracle.csproj | 2 +- .../FreeSql.Provider.PostgreSQL.csproj | 2 +- .../FreeSql.Provider.SqlServer.csproj | 2 +- .../FreeSql.Provider.Sqlite.csproj | 2 +- 16 files changed, 265 insertions(+), 42 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs create mode 100644 FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index ac4b783f..90b5313a 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.DbContext/FreeSql.DbContext.csproj b/FreeSql.DbContext/FreeSql.DbContext.csproj index 99c37e9c..548e045c 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.csproj +++ b/FreeSql.DbContext/FreeSql.DbContext.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index acb5b2fd..2c3d3f9a 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 YeXiangQin FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table. https://github.com/2881099/FreeSql/wiki/Repository diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj index 902899b6..cee654fa 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.csproj @@ -21,7 +21,6 @@ - diff --git a/FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs b/FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs new file mode 100644 index 00000000..788cafab --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/CustomerCheckupGroup.cs @@ -0,0 +1,89 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// Website: http://www.freesql.net +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; + +namespace ZX.Model { + + [JsonObject(MemberSerialization.OptIn)] + public class CustomerCheckupGroup { + + [JsonProperty, Column(IsPrimary = true)] + public short ShopId { get => _ShopId; set { + if (_ShopId == value) return; + _ShopId = value; + } } + private short _ShopId; + + [JsonProperty, Column(DbType = "varchar(50)", IsPrimary = true)] + public string Id { get; set; } + + [JsonProperty, Column(DbType = "nvarchar(50)")] + public string MemberId { get => _MemberId; set { + if (_MemberId == value) return; + _MemberId = value; + } } + private string _MemberId; + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Discount { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Doctor { get; set; } + + [JsonProperty] + public DateTime? FirstTime { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Group { get; set; } + + [JsonProperty] + public DateTime? InsertTime { get; set; } + + [JsonProperty, Column(Name = "isOK")] + public bool? IsOK { get; set; } + + [JsonProperty, Column(Name = "isPay", DbType = "varchar(50)")] + public string IsPay { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Office { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string PayType { get; set; } + + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal? Price { get; set; } + + [JsonProperty] + public DateTime? UpdateTime { get; set; } + + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal? Value { get; set; } + + + #region 外键 => 导航属性,ManyToOne/OneToOne + + [Navigate("ShopId, MemberId")] + public virtual CustomerMember CustomerMember { get; set; } + #endregion + + #region 外键 => 导航属性,ManyToMany + + #endregion + } + +} diff --git a/FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs b/FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs new file mode 100644 index 00000000..fabf1500 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/Other/CustomerMember.cs @@ -0,0 +1,108 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// Website: http://www.freesql.net +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Newtonsoft.Json; +using FreeSql.DataAnnotations; + +namespace ZX.Model { + + [JsonObject(MemberSerialization.OptIn)] + public class CustomerMember { + public CustomerMember() + { + CheckupGroups = new List(); + } + + [JsonProperty, Column(DbType = "nvarchar(50)", IsPrimary = true)] + public string MemberId { get; set; } + + [JsonProperty, Column(IsPrimary = true)] + public short ShopId { get; set; } + + [JsonProperty] + public long? CustomerId { get => _CustomerId; set { + if (_CustomerId == value) return; + _CustomerId = value; + } } + private long? _CustomerId; + + [JsonProperty, Column(DbType = "varchar(500)")] + public string Address { get; set; } + + [JsonProperty, Column(DbType = "smalldatetime")] + public DateTime? Birthday { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string CardNo { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string CardType { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Doctor { get; set; } + + [JsonProperty] + public DateTime? EndDate { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Group { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Marry { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Name { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Part { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string PayType { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Phone { get; set; } + + [JsonProperty, Column(DbType = "varchar(10)")] + public string Sex { get; set; } + + [JsonProperty] + public DateTime? StartDate { get; set; } + + [JsonProperty, Column(DbType = "text")] + public string Suggest { get; set; } + + [JsonProperty, Column(DbType = "text")] + public string SumUp { get; set; } + + [JsonProperty, Column(DbType = "varchar(50)")] + public string Team { get; set; } + + [JsonProperty, Column(DbType = "decimal(9,2)")] + public decimal? TotalFee { get; set; } + + + #region 外键 => 导航属性,ManyToOne/OneToOne + + [Navigate("MemberId,ShopId")] + public virtual List CheckupGroups { get; set; } + + #endregion + + #region 外键 => 导航属性,ManyToMany + + #endregion + } + +} diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs index 4a011e01..858210f7 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest1.cs @@ -296,6 +296,14 @@ namespace FreeSql.Tests [Fact] public void Test1() { + var teklksjdg = g.sqlite.Select() + .Where(a => true && a.CustomerMember.Group == "xxx") + .ToSql(); + + var sklgjlskdg = g.sqlite.Select() + .Where(a => a.CheckupGroups.AsSelect().Any()) + .ToSql(); + var tkdkdksql = g.sqlite.Select().From((a, b, c) => a.LeftJoin(aa => aa.TemplatesId == b.Id2 && b.Code == "xx") .LeftJoin(aa => aa.TemplatesId == c.Id2)) diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 5ef4f348..f5ebe4dc 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 5566635b..44fcb327 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -327,16 +327,7 @@ namespace FreeSql.Internal if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) return $"{sql} = {formatSql(true, null)}"; if (isBool) - { - switch (sql) - { - case "1": - case "'t'": return "1=1"; - case "0": - case "'f'": return "1=2"; - default: return sql; - } - } + return GetBoolString(sql); return sql; } @@ -347,16 +338,7 @@ namespace FreeSql.Internal if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) return $"{sql} = {formatSql(true, null)}"; if (isBool) - { - switch (sql) - { - case "1": - case "'t'": return "1=1"; - case "0": - case "'f'": return "1=2"; - default: return sql; - } - } + return GetBoolString(sql); return sql; } public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, Func getSelectGroupingMapString) @@ -367,16 +349,8 @@ namespace FreeSql.Internal if (exp.NodeType == ExpressionType.MemberAccess && isBool && sql.Contains(" IS ") == false && sql.Contains(" = ") == false) sql = $"{sql} = {formatSql(true, null)}"; if (isBool) - { - switch (sql) - { - case "1": - case "'t'": sql = "1=1"; break; - case "0": - case "'f'": sql = "1=2"; break; - default: break; - } - } + sql = GetBoolString(sql); + if (_tables.Count > tbidx) { _tables[tbidx].Type = tbtype; @@ -403,6 +377,17 @@ namespace FreeSql.Internal static MethodInfo MethodDateTimeSubtractDateTime = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(DateTime) }); static MethodInfo MethodDateTimeSubtractTimeSpan = typeof(DateTime).GetMethod("Subtract", new Type[] { typeof(TimeSpan) }); + static string GetBoolString(string sql) + { + switch (sql) + { + case "1": + case "'t'": return "1=1"; + case "0": + case "'f'": return "1=2"; + default: return sql; + } + } public string ExpressionBinary(string oper, Expression leftExp, Expression rightExp, ExpTSC tsc) { switch (oper) @@ -483,7 +468,15 @@ namespace FreeSql.Internal left = tmp; } if (right == "NULL") oper = oper == "=" ? " IS " : " IS NOT "; - if (oper == "%") return _common.Mod(left, right, leftExp.Type, rightExp.Type); + switch(oper) + { + case "%": return _common.Mod(left, right, leftExp.Type, rightExp.Type); + case "AND": + case "OR": + left = GetBoolString(left); + right = GetBoolString(right); + break; + } tsc.mapType = null; return $"{left} {oper} {right}"; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 8f3ee4cb..6fc8eb7a 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -568,6 +568,19 @@ namespace FreeSql.Internal trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; } + if (trytb.Primarys.Length > 1) + { + if (trytb.Primarys.Select(a => a.CsType).Distinct().Count() == trytb.Primarys.Length) + { + var pkList = trytb.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType == a.CsType).CompareTo(pkList.FindIndex(c => c.CsType == b.CsType))); + } + else if (string.Compare(string.Join(",", trytb.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) + { + var pkList = trytb.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => string.Compare(c.CsName, a.CsName, true) == 0).CompareTo(pkList.FindIndex(c => string.Compare(c.CsName, b.CsName, true) == 0))); + } + } for (var a = 0; nvref.Exception == null && a < trytb.Primarys.Length; a++) { var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_'); @@ -705,6 +718,19 @@ namespace FreeSql.Internal trytb.AddOrUpdateTableRef(pnv.Name, nvref); //if (isLazy) throw nvref.Exception; } + if (tbref.Primarys.Length > 1) + { + if (tbref.Primarys.Select(a => a.CsType).Distinct().Count() == tbref.Primarys.Length) + { + var pkList = tbref.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => c.CsType == a.CsType).CompareTo(pkList.FindIndex(c => c.CsType == b.CsType))); + } + else if (string.Compare(string.Join(",", tbref.Primarys.Select(a => a.CsName).OrderBy(a => a)), string.Join(",", bindColumns.Select(a => a.CsName).OrderBy(a => a)), true) == 0) + { + var pkList = tbref.Primarys.ToList(); + bindColumns.Sort((a, b) => pkList.FindIndex(c => string.Compare(c.CsName, a.CsName, true) == 0).CompareTo(pkList.FindIndex(c => string.Compare(c.CsName, b.CsName, true) == 0))); + } + } for (var a = 0; nvref.Exception == null && a < tbref.Primarys.Length; a++) { var findtbrefPkCsName = tbref.Primarys[a].CsName.TrimStart('_'); diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 18eb5909..44ffbd57 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 0a3fd69b..07ee9fc6 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index 119e72f9..379531f7 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 1070d36e..83927cbf 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index 089db883..1bb32c90 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5dda69b3..d7328e69 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.7.5 + 0.7.6 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0