mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	Merge pull request #1195 from xunapro/master
fix: 修复实体对象无空构造函数时通过Repository操作引发异常的问题,增加Lazy改进并发
This commit is contained in:
		@@ -219,7 +219,7 @@ namespace FreeSql
 | 
			
		||||
        public DbSet<TEntity> AttachOnlyPrimary(TEntity data)
 | 
			
		||||
        {
 | 
			
		||||
            if (data == null) return this;
 | 
			
		||||
            var pkitem = (TEntity)Activator.CreateInstance(_entityType);
 | 
			
		||||
            var pkitem = (TEntity)_entityType.CreateInstanceGetDefaultValue();
 | 
			
		||||
            foreach (var pk in _db.OrmOriginal.CodeFirst.GetTableByEntity(_entityType).Primarys)
 | 
			
		||||
            {
 | 
			
		||||
                var colVal = _db.OrmOriginal.GetEntityValueWithPropertyName(_entityType, data, pk.CsName);
 | 
			
		||||
@@ -267,8 +267,8 @@ namespace FreeSql
 | 
			
		||||
        {
 | 
			
		||||
            if (data == null) throw new ArgumentNullException(nameof(data));
 | 
			
		||||
            var key = _db.OrmOriginal.GetEntityKeyString(_entityType, data, false);
 | 
			
		||||
            var state = new EntityState((TEntity)Activator.CreateInstance(_entityType), key);
 | 
			
		||||
            _db.OrmOriginal.MapEntityValue(_entityType, data, state.Value);
 | 
			
		||||
            var state = new EntityState((TEntity)_entityType.CreateInstanceGetDefaultValue(), key);
 | 
			
		||||
           _db.OrmOriginal.MapEntityValue(_entityType, data, state.Value);
 | 
			
		||||
            return state;
 | 
			
		||||
        }
 | 
			
		||||
        bool? ExistsInStates(TEntity data)
 | 
			
		||||
 
 | 
			
		||||
@@ -312,7 +312,7 @@ namespace FreeSql
 | 
			
		||||
                            midSet.RemoveRange(midListDel); //删除未保存的项
 | 
			
		||||
                            foreach (var curItem in curList)
 | 
			
		||||
                            {
 | 
			
		||||
                                var newItem = Activator.CreateInstance(tref.RefMiddleEntityType);
 | 
			
		||||
                                var newItem = tref.RefMiddleEntityType.CreateInstanceGetDefaultValue();
 | 
			
		||||
                                for (var colidx = 0; colidx < tref.Columns.Count; colidx++)
 | 
			
		||||
                                {
 | 
			
		||||
                                    var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[colidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName));
 | 
			
		||||
 
 | 
			
		||||
@@ -323,7 +323,7 @@ namespace FreeSql
 | 
			
		||||
                            midSet.RemoveRange(midListDel); //删除未保存的项
 | 
			
		||||
                            foreach (var curItem in curList)
 | 
			
		||||
                            {
 | 
			
		||||
                                var newItem = Activator.CreateInstance(tref.RefMiddleEntityType);
 | 
			
		||||
                                var newItem = tref.RefMiddleEntityType.CreateInstanceGetDefaultValue();
 | 
			
		||||
                                for (var colidx = 0; colidx < tref.Columns.Count; colidx++)
 | 
			
		||||
                                {
 | 
			
		||||
                                    var val = FreeSql.Internal.Utils.GetDataReaderValue(tref.MiddleColumns[colidx].CsType, _db.OrmOriginal.GetEntityValueWithPropertyName(_table.Type, item, tref.Columns[colidx].CsName));
 | 
			
		||||
 
 | 
			
		||||
@@ -197,7 +197,7 @@ namespace FreeSql
 | 
			
		||||
            var tb = _db.OrmOriginal.CodeFirst.GetTableByEntity(EntityType);
 | 
			
		||||
            if (tb.Primarys.Length != 1) throw new Exception(DbContextStrings.EntityType_PrimaryKeyIsNotOne(EntityType.Name));
 | 
			
		||||
            if (tb.Primarys[0].CsType.NullableTypeOrThis() != typeof(TKey).NullableTypeOrThis()) throw new Exception(DbContextStrings.EntityType_PrimaryKeyError(EntityType.Name, typeof(TKey).FullName));
 | 
			
		||||
            var obj = Activator.CreateInstance(tb.Type);
 | 
			
		||||
            var obj = tb.Type.CreateInstanceGetDefaultValue();
 | 
			
		||||
            _db.OrmOriginal.SetEntityValueWithPropertyName(tb.Type, obj, tb.Primarys[0].CsName, id);
 | 
			
		||||
            var ret = obj as TEntity;
 | 
			
		||||
            if (ret == null) throw new Exception(DbContextStrings.EntityType_CannotConvert(EntityType.Name, typeof(TEntity).Name));
 | 
			
		||||
 
 | 
			
		||||
@@ -151,14 +151,19 @@ public static partial class FreeSqlGlobalExtensions
 | 
			
		||||
        return Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Constant(a.ParameterType.CreateInstanceGetDefaultValue(), a.ParameterType)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static ConcurrentDictionary<Type, ConstructorInfo> _dicInternalGetTypeConstructor0OrFirst = new ConcurrentDictionary<Type, ConstructorInfo>();
 | 
			
		||||
    static ConcurrentDictionary<Type, Lazy<ConstructorInfo>> _dicInternalGetTypeConstructor0OrFirst = new ConcurrentDictionary<Type, Lazy<ConstructorInfo>>();
 | 
			
		||||
    internal static ConstructorInfo InternalGetTypeConstructor0OrFirst(this Type that, bool isThrow = true)
 | 
			
		||||
    {
 | 
			
		||||
        var ret = _dicInternalGetTypeConstructor0OrFirst.GetOrAdd(that, tp =>
 | 
			
		||||
            tp.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null) ??
 | 
			
		||||
            tp.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).OrderBy(a => a.IsPublic ? 0 : 1).FirstOrDefault());
 | 
			
		||||
        if (ret == null && isThrow) throw new ArgumentException(CoreStrings.Type_Cannot_Access_Constructor(that.FullName));
 | 
			
		||||
        return ret;
 | 
			
		||||
            new Lazy<ConstructorInfo>(() =>
 | 
			
		||||
            {
 | 
			
		||||
                return tp.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null) ??
 | 
			
		||||
                    tp.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
 | 
			
		||||
                    .OrderBy(a => a.IsPublic ? 0 : 1)
 | 
			
		||||
                    .FirstOrDefault();
 | 
			
		||||
            }));
 | 
			
		||||
        if (ret.Value == null && isThrow) throw new ArgumentException(CoreStrings.Type_Cannot_Access_Constructor(that.FullName));
 | 
			
		||||
        return ret.Value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static ConcurrentDictionary<Type, Dictionary<string, PropertyInfo>> _dicGetPropertiesDictIgnoreCase = new ConcurrentDictionary<Type, Dictionary<string, PropertyInfo>>();
 | 
			
		||||
@@ -466,7 +471,7 @@ public static partial class FreeSqlGlobalExtensions
 | 
			
		||||
                if (keyval.Length != 2) throw new ArgumentException(CoreStrings.ParameterError_NotValid_UseCommas(nameof(where)));
 | 
			
		||||
 | 
			
		||||
                if (reftb.ColumnsByCs.TryGetValue(keyval[0], out var keycol) == false)
 | 
			
		||||
                    throw new ArgumentException(CoreStrings.ParameterError_NotValid_PropertyName(nameof(where),keyval[0], reftb.Type.DisplayCsharp()));
 | 
			
		||||
                    throw new ArgumentException(CoreStrings.ParameterError_NotValid_PropertyName(nameof(where), keyval[0], reftb.Type.DisplayCsharp()));
 | 
			
		||||
                if (parTb.ColumnsByCs.TryGetValue(keyval[1], out var valcol) == false)
 | 
			
		||||
                    throw new ArgumentException(CoreStrings.ParameterError_NotValid_PropertyName(nameof(where), keyval[1], parTb.Type.DisplayCsharp()));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user