diff --git a/src/EFCore.Sharding.MySql/EFCore.Sharding.MySql.csproj b/src/EFCore.Sharding.MySql/EFCore.Sharding.MySql.csproj index 4844e8f..c1dfc7a 100644 --- a/src/EFCore.Sharding.MySql/EFCore.Sharding.MySql.csproj +++ b/src/EFCore.Sharding.MySql/EFCore.Sharding.MySql.csproj @@ -8,7 +8,7 @@ https://github.com/Coldairarrow/EFCore.Sharding https://github.com/Coldairarrow/EFCore.Sharding github - 3.1.6.1 + 3.1.6.2 diff --git a/src/EFCore.Sharding.PostgreSql/EFCore.Sharding.PostgreSql.csproj b/src/EFCore.Sharding.PostgreSql/EFCore.Sharding.PostgreSql.csproj index dce68c2..53eb728 100644 --- a/src/EFCore.Sharding.PostgreSql/EFCore.Sharding.PostgreSql.csproj +++ b/src/EFCore.Sharding.PostgreSql/EFCore.Sharding.PostgreSql.csproj @@ -8,7 +8,7 @@ https://github.com/Coldairarrow/EFCore.Sharding https://github.com/Coldairarrow/EFCore.Sharding github - 3.1.6.1 + 3.1.6.2 diff --git a/src/EFCore.Sharding.SQLite/EFCore.Sharding.SQLite.csproj b/src/EFCore.Sharding.SQLite/EFCore.Sharding.SQLite.csproj index f64861b..6dae8cb 100644 --- a/src/EFCore.Sharding.SQLite/EFCore.Sharding.SQLite.csproj +++ b/src/EFCore.Sharding.SQLite/EFCore.Sharding.SQLite.csproj @@ -8,7 +8,7 @@ https://github.com/Coldairarrow/EFCore.Sharding https://github.com/Coldairarrow/EFCore.Sharding github - 3.1.6.1 + 3.1.6.2 diff --git a/src/EFCore.Sharding.SqlServer/EFCore.Sharding.SqlServer.csproj b/src/EFCore.Sharding.SqlServer/EFCore.Sharding.SqlServer.csproj index d591891..d067a8f 100644 --- a/src/EFCore.Sharding.SqlServer/EFCore.Sharding.SqlServer.csproj +++ b/src/EFCore.Sharding.SqlServer/EFCore.Sharding.SqlServer.csproj @@ -8,7 +8,7 @@ https://github.com/Coldairarrow/EFCore.Sharding https://github.com/Coldairarrow/EFCore.Sharding github - 3.1.6.1 + 3.1.6.2 diff --git a/src/EFCore.Sharding.Tests/Sharding/ShardingHelperTest.cs b/src/EFCore.Sharding.Tests/Sharding/ShardingHelperTest.cs new file mode 100644 index 0000000..38124b5 --- /dev/null +++ b/src/EFCore.Sharding.Tests/Sharding/ShardingHelperTest.cs @@ -0,0 +1,121 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq.Dynamic.Core; +using System.Linq.Expressions; + +namespace EFCore.Sharding.Tests.Sharding +{ + [TestClass] + public class ShardingHelperTest + { + private readonly static string _table1 = new string[] { "202001" }.ToJson(); + private readonly static string _table2 = new string[] { "202002" }.ToJson(); + private readonly static string _table3 = new string[] { "202003" }.ToJson(); + private readonly static string _table123 = new string[] { "202001", "202002", "202003" }.ToJson(); + private readonly static string _table12 = new string[] { "202001", "202002" }.ToJson(); + private readonly static string _table23 = new string[] { "202002", "202003" }.ToJson(); + + [TestMethod] + public void FilterTable() + { + var db = Startup.ServiceProvider.GetService(); + + var q = db.GetIQueryable(); + ShardingRule rule = new ShardingRule + { + EntityType = typeof(Base_UnitTest), + ExpandByDateMode = ExpandByDateMode.PerMonth, + ShardingField = nameof(Base_UnitTest.CreateTime), + ShardingType = ShardingType.Date + }; + List tableSuffixs = new List() { "202001", "202002", "202003" }; + DateTime time0 = DateTime.Parse("2019-12-01"); + DateTime time1 = DateTime.Parse("2020-01-01"); + DateTime time2 = DateTime.Parse("2020-02-01"); + DateTime time3 = DateTime.Parse("2020-03-01"); + DateTime time4 = DateTime.Parse("2020-04-01"); + List res; + //= + res = GetFilterTable(x => x.CreateTime == time1); + Assert.AreEqual(res.ToJson(), _table1); + + res = GetFilterTable(x => x.CreateTime == time0); + Assert.AreEqual(res.Count, 0); + + res = GetFilterTable(x => x.CreateTime == time4); + Assert.AreEqual(res.Count, 0); + //!= + res = GetFilterTable(x => x.CreateTime != time1); + Assert.AreEqual(res.ToJson(), _table23); + + res = GetFilterTable(x => x.CreateTime != time0); + Assert.AreEqual(res.ToJson(), _table123); + + res = GetFilterTable(x => x.CreateTime != time4); + Assert.AreEqual(res.ToJson(), _table123); + //> + res = GetFilterTable(x => x.CreateTime > time0); + Assert.AreEqual(res.ToJson(), _table123); + + res = GetFilterTable(x => x.CreateTime > time2); + Assert.AreEqual(res.ToJson(), _table23); + + res = GetFilterTable(x => x.CreateTime > time3); + Assert.AreEqual(res.Count, 1); + + res = GetFilterTable(x => x.CreateTime > time4); + Assert.AreEqual(res.Count, 0); + //>= + res = GetFilterTable(x => x.CreateTime > time0); + Assert.AreEqual(res.ToJson(), _table123); + + res = GetFilterTable(x => x.CreateTime > time1); + Assert.AreEqual(res.ToJson(), _table123); + + res = GetFilterTable(x => x.CreateTime > time2); + Assert.AreEqual(res.ToJson(), _table23); + + res = GetFilterTable(x => x.CreateTime > time3); + Assert.AreEqual(res.Count, 1); + + res = GetFilterTable(x => x.CreateTime > time4); + Assert.AreEqual(res.Count, 0); + //< + res = GetFilterTable(x => x.CreateTime < time0); + Assert.AreEqual(res.Count, 0); + + res = GetFilterTable(x => x.CreateTime < time1); + Assert.AreEqual(res.ToJson(), _table1); + + res = GetFilterTable(x => x.CreateTime < time2); + Assert.AreEqual(res.ToJson(), _table12); + + res = GetFilterTable(x => x.CreateTime < time3); + Assert.AreEqual(res.ToJson(), _table123); + + res = GetFilterTable(x => x.CreateTime < time4); + Assert.AreEqual(res.ToJson(), _table123); + //<= + res = GetFilterTable(x => x.CreateTime < time0); + Assert.AreEqual(res.Count, 0); + + res = GetFilterTable(x => x.CreateTime < time1); + Assert.AreEqual(res.ToJson(), _table1); + + res = GetFilterTable(x => x.CreateTime < time2); + Assert.AreEqual(res.ToJson(), _table12); + + res = GetFilterTable(x => x.CreateTime < time3); + Assert.AreEqual(res.ToJson(), _table123); + + res = GetFilterTable(x => x.CreateTime < time4); + + Assert.AreEqual(res.ToJson(), _table123); List GetFilterTable(Expression> theWhere) + { + return ShardingHelper.FilterTable(db.GetIQueryable().Where(theWhere), tableSuffixs, rule); + } + } + } +} diff --git a/src/EFCore.Sharding.Tests/00Util/Extention.DataTable.cs b/src/EFCore.Sharding.Tests/Util/Extention.DataTable.cs similarity index 100% rename from src/EFCore.Sharding.Tests/00Util/Extention.DataTable.cs rename to src/EFCore.Sharding.Tests/Util/Extention.DataTable.cs diff --git a/src/EFCore.Sharding.Tests/00Util/Extention.IEnumerable.cs b/src/EFCore.Sharding.Tests/Util/Extention.IEnumerable.cs similarity index 100% rename from src/EFCore.Sharding.Tests/00Util/Extention.IEnumerable.cs rename to src/EFCore.Sharding.Tests/Util/Extention.IEnumerable.cs diff --git a/src/EFCore.Sharding.Tests/00Util/Extention.Object.cs b/src/EFCore.Sharding.Tests/Util/Extention.Object.cs similarity index 100% rename from src/EFCore.Sharding.Tests/00Util/Extention.Object.cs rename to src/EFCore.Sharding.Tests/Util/Extention.Object.cs diff --git a/src/EFCore.Sharding.Tests/00Util/Extention.String.cs b/src/EFCore.Sharding.Tests/Util/Extention.String.cs similarity index 100% rename from src/EFCore.Sharding.Tests/00Util/Extention.String.cs rename to src/EFCore.Sharding.Tests/Util/Extention.String.cs diff --git a/src/EFCore.Sharding/EFCore.Sharding.csproj b/src/EFCore.Sharding/EFCore.Sharding.csproj index fdefd93..20e0ea0 100644 --- a/src/EFCore.Sharding/EFCore.Sharding.csproj +++ b/src/EFCore.Sharding/EFCore.Sharding.csproj @@ -9,7 +9,7 @@ https://github.com/Coldairarrow/EFCore.Sharding https://github.com/Coldairarrow/EFCore.Sharding github - 3.1.6.1 + 3.1.6.2 true diff --git a/src/EFCore.Sharding/Primitives/ShardingRule.cs b/src/EFCore.Sharding/Primitives/ShardingRule.cs index 0385cad..3cdd792 100644 --- a/src/EFCore.Sharding/Primitives/ShardingRule.cs +++ b/src/EFCore.Sharding/Primitives/ShardingRule.cs @@ -5,7 +5,6 @@ namespace EFCore.Sharding internal class ShardingRule { public Type EntityType { get; set; } - public string TableName { get => AnnotationHelper.GetDbTableName(EntityType); } public ShardingType ShardingType { get; set; } public string ShardingField { get; set; } public int Mod { get; set; } diff --git a/src/EFCore.Sharding/Properties/AssemblyInfo.cs b/src/EFCore.Sharding/Properties/AssemblyInfo.cs index 7074952..d070ff2 100644 --- a/src/EFCore.Sharding/Properties/AssemblyInfo.cs +++ b/src/EFCore.Sharding/Properties/AssemblyInfo.cs @@ -4,4 +4,4 @@ [assembly: InternalsVisibleTo("EFCore.Sharding.PostgreSql")] [assembly: InternalsVisibleTo("EFCore.Sharding.SQLite")] [assembly: InternalsVisibleTo("EFCore.Sharding.SqlServer")] -[assembly: InternalsVisibleTo("Demo.Performance")] \ No newline at end of file +[assembly: InternalsVisibleTo("EFCore.Sharding.Tests")] \ No newline at end of file diff --git a/src/EFCore.Sharding/Sharding/ShardingHelper.cs b/src/EFCore.Sharding/Sharding/ShardingHelper.cs index 801c32c..d9a603c 100644 --- a/src/EFCore.Sharding/Sharding/ShardingHelper.cs +++ b/src/EFCore.Sharding/Sharding/ShardingHelper.cs @@ -127,9 +127,9 @@ private Expression> GetWhere(BinaryExpression binaryExpression) string op = binaryExpression.NodeType switch { - ExpressionType.GreaterThan => paramterAtLeft ? ">" : "<", + ExpressionType.GreaterThan => paramterAtLeft ? ">=" : "<=", ExpressionType.GreaterThanOrEqual => paramterAtLeft ? ">=" : "<=", - ExpressionType.LessThan => paramterAtLeft ? "<" : ">", + ExpressionType.LessThan => paramterAtLeft ? "<=" : ">=", ExpressionType.LessThanOrEqual => paramterAtLeft ? "<=" : ">=", ExpressionType.Equal => "==", ExpressionType.NotEqual => "!=", @@ -139,17 +139,22 @@ private Expression> GetWhere(BinaryExpression binaryExpression) if (op == null || value == null) return x => true; - string tableSuffix = value.Value.ToString("yyyyMMddHHmmss"); - var newTableSuffixs = _allTableSuffixs.Concat(new string[] { tableSuffix }).OrderBy(x => x).ToList(); - int index = newTableSuffixs.IndexOf(tableSuffix); + string realSuffix = _rule.GetTableSuffixByField(value.Value); + int index = _allTableSuffixs.IndexOf(realSuffix); - if (binaryExpression.NodeType == ExpressionType.GreaterThan - || binaryExpression.NodeType == ExpressionType.GreaterThanOrEqual - || binaryExpression.NodeType == ExpressionType.Equal - || binaryExpression.NodeType == ExpressionType.NotEqual - ) + //超出范围 + if (index == -1) { - index = index - 1; + string fullSuffix = value.Value.ToString("yyyyMMddHHmmss"); + var newTableSuffixs = _allTableSuffixs.Concat(new string[] { fullSuffix }).OrderBy(x => x).ToList(); + int fullIndex = newTableSuffixs.IndexOf(fullSuffix); + + if (fullIndex == 0 && (op == ">=" || op == "!=")) + return x => true; + else if (fullIndex == newTableSuffixs.Count - 1 && (op == "<=" || op == "!=")) + return x => true; + else + return x => false; } var newWhere = DynamicExpressionParser.ParseLambda( diff --git a/src/EFCore.Sharding/Util/Extention.Object.cs b/src/EFCore.Sharding/Util/Extention.Object.cs index 0ec7585..1e97bdf 100644 --- a/src/EFCore.Sharding/Util/Extention.Object.cs +++ b/src/EFCore.Sharding/Util/Extention.Object.cs @@ -1,6 +1,7 @@ using Castle.DynamicProxy; using Dynamitey; using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; using System; using System.ComponentModel; using System.Reflection; @@ -9,6 +10,17 @@ namespace EFCore.Sharding { internal static partial class Extention { + static Extention() + { + JsonConvert.DefaultSettings = () => DefaultJsonSetting; + } + public static JsonSerializerSettings DefaultJsonSetting = new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver(), + DateFormatHandling = DateFormatHandling.MicrosoftDateFormat, + DateFormatString = "yyyy-MM-dd HH:mm:ss.fff" + }; + private static readonly BindingFlags _bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static; private static readonly ProxyGenerator Generator = new ProxyGenerator();