From a0e18b1a687967c54caded5b798429eb0f518138 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sun, 19 Apr 2020 00:09:24 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20FreeSql.Extensions.Jso?= =?UTF-8?q?nMap=20FluentApi=20=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=9B#279?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 13 ++- .../FreeSql.Extensions.JsonMap.xml | 2 +- .../FreeSql.Extensions.JsonMap/JsonMapCore.cs | 92 ++++++++++--------- FreeSql.DbContext/FreeSql.DbContext.xml | 16 ---- FreeSql/DataAnnotations/ColumnFluent.cs | 10 +- FreeSql/DataAnnotations/TableFluent.cs | 8 +- 6 files changed, 70 insertions(+), 71 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 0db13185..e800ef21 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -27,6 +27,8 @@ namespace base_entity [JsonMap] public T Config { get; set; } + + public T Config2 { get; set; } } public class Products : BaseEntity @@ -89,10 +91,15 @@ namespace base_entity var items2 = fsql.Select().Limit(10).OrderByDescending(a => a.CreateTime).ToList(); BaseEntity.Orm.UseJsonMap(); + BaseEntity.Orm.UseJsonMap(); + BaseEntity.Orm.CodeFirst.ConfigEntity>(a => + { + a.Property(b => b.Config2).JsonMap(); + }); - new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); - new S_SysConfig { Name = "testkey22", Config = new TestConfig { clicks = 22, title = "testtitle22" } }.Save(); - new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" } }.Save(); + new S_SysConfig { Name = "testkey11", Config = new TestConfig { clicks = 11, title = "testtitle11" }, Config2 = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); + new S_SysConfig { Name = "testkey22", Config = new TestConfig { clicks = 22, title = "testtitle22" }, Config2 = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); + new S_SysConfig { Name = "testkey33", Config = new TestConfig { clicks = 33, title = "testtitle33" }, Config2 = new TestConfig { clicks = 11, title = "testtitle11" } }.Save(); var testconfigs11 = S_SysConfig.Select.ToList(); var repo = BaseEntity.Orm.Select().Limit(10).ToList(); diff --git a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml index 6c47f3b3..9829e929 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml +++ b/Extensions/FreeSql.Extensions.JsonMap/FreeSql.Extensions.JsonMap.xml @@ -9,7 +9,7 @@ 当实体类属性为【对象】时,以JSON形式映射存储 - + 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 diff --git a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs index 32647dae..a0f6855d 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs +++ b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs @@ -6,59 +6,61 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Threading; -namespace FreeSql.Extensions +public static class FreeSqlJsonMapCoreExtensions { - public static class JsonMapCore + static int _isAoped = 0; + static ConcurrentDictionary _dicTypes = new ConcurrentDictionary(); + static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); + static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object), typeof(JsonSerializerSettings) }); + static ConcurrentDictionary> _dicJsonMapFluentApi = new ConcurrentDictionary>(); + + public static ColumnFluent JsonMap(this ColumnFluent col) { - static bool _isAoped = false; - static object _isAopedLock = new object(); - static ConcurrentDictionary _dicTypes = new ConcurrentDictionary(); - static MethodInfo MethodJsonConvertDeserializeObject = typeof(JsonConvert).GetMethod("DeserializeObject", new[] { typeof(string), typeof(Type) }); - static MethodInfo MethodJsonConvertSerializeObject = typeof(JsonConvert).GetMethod("SerializeObject", new[] { typeof(object), typeof(JsonSerializerSettings) }); + _dicJsonMapFluentApi.GetOrAdd(col._entityType, et => new ConcurrentDictionary()) + .GetOrAdd(col._property.Name, pn => true); + return col; + } - /// - /// 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 - /// - /// - public static void UseJsonMap(this IFreeSql that) + /// + /// 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 + /// + /// + public static void UseJsonMap(this IFreeSql that) + { + UseJsonMap(that, JsonConvert.DefaultSettings?.Invoke() ?? new JsonSerializerSettings()); + } + + public static void UseJsonMap(this IFreeSql that, JsonSerializerSettings settings) + { + if (Interlocked.CompareExchange(ref _isAoped, 1, 0) == 0) { - UseJsonMap(that, Newtonsoft.Json.JsonConvert.DefaultSettings?.Invoke() ?? new JsonSerializerSettings()); + FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => + { + if (_dicTypes.ContainsKey(type)) return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type)), type)); + return null; + }); } - public static void UseJsonMap(this IFreeSql that, JsonSerializerSettings settings) + that.Aop.ConfigEntityProperty += new EventHandler((s, e) => { - if (_isAoped == false) - lock (_isAopedLock) - if (_isAoped == false) + var isJsonMap = e.Property.GetCustomAttributes(typeof(JsonMapAttribute), false).Any() || _dicJsonMapFluentApi.TryGetValue(e.EntityType, out var tryjmfu) && tryjmfu.ContainsKey(e.Property.Name); + if (isJsonMap) + { + e.ModifyResult.MapType = typeof(string); + if (_dicTypes.TryAdd(e.Property.PropertyType, true)) + { + FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionObjectToStringIfThenElse.Add((LabelTarget returnTarget, Expression valueExp, Expression elseExp, Type type) => { - _isAoped = true; - - FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionSwitchTypeFullName.Add((LabelTarget returnTarget, Expression valueExp, Type type) => - { - if (_dicTypes.ContainsKey(type)) return Expression.Return(returnTarget, Expression.TypeAs(Expression.Call(MethodJsonConvertDeserializeObject, Expression.Convert(valueExp, typeof(string)), Expression.Constant(type)), type)); - return null; - }); - - that.Aop.ConfigEntityProperty += new EventHandler((s, e) => - { - if (e.Property.GetCustomAttributes(typeof(JsonMapAttribute), false).Any()) - { - e.ModifyResult.MapType = typeof(string); - if (_dicTypes.TryAdd(e.Property.PropertyType, true)) - { - FreeSql.Internal.Utils.GetDataReaderValueBlockExpressionObjectToStringIfThenElse.Add((LabelTarget returnTarget, Expression valueExp, Expression elseExp, Type type) => - { - return Expression.IfThenElse( - Expression.TypeEqual(valueExp, e.Property.PropertyType), - Expression.Return(returnTarget, Expression.Call(MethodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object)), Expression.Constant(settings)), typeof(object)), - elseExp); - }); - } - } - }); - } - } - + return Expression.IfThenElse( + Expression.TypeEqual(valueExp, e.Property.PropertyType), + Expression.Return(returnTarget, Expression.Call(MethodJsonConvertSerializeObject, Expression.Convert(valueExp, typeof(object)), Expression.Constant(settings)), typeof(object)), + elseExp); + }); + } + } + }); } } + diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 8fd2938a..299c91e5 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -120,13 +120,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -395,14 +388,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index 2a897e6f..4a1adc93 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -1,16 +1,22 @@ using System; +using System.Collections.Generic; +using System.Reflection; namespace FreeSql.DataAnnotations { public class ColumnFluent { - public ColumnFluent(ColumnAttribute column) + public ColumnFluent(ColumnAttribute column, PropertyInfo property, Type entityType) { _column = column; + _property = property; + _entityType = entityType; } - ColumnAttribute _column; + public ColumnAttribute _column; + public PropertyInfo _property; + public Type _entityType; /// /// 数据库列名 /// diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index f1e93d42..46c1f760 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -47,9 +47,9 @@ namespace FreeSql.DataAnnotations public ColumnFluent Property(string proto) { - if (_properties.ContainsKey(proto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); - var col = _table._columns.GetOrAdd(proto, name => new ColumnAttribute { Name = proto }); - return new ColumnFluent(col); + if (_properties.TryGetValue(proto, out var tryProto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); + var col = _table._columns.GetOrAdd(tryProto.Name, name => new ColumnAttribute { Name = proto }); + return new ColumnFluent(col, tryProto, _entityType); } /// @@ -131,7 +131,7 @@ namespace FreeSql.DataAnnotations { if (_properties.TryGetValue(proto, out var tryProto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); var col = _table._columns.GetOrAdd(tryProto.Name, name => new ColumnAttribute { Name = proto }); - return new ColumnFluent(col); + return new ColumnFluent(col, tryProto, typeof(T)); } ///