mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	完成延时加载开发与测试,ICollection集合待支持
This commit is contained in:
		@@ -10,28 +10,39 @@ namespace FreeSql.Tests.MySql {
 | 
				
			|||||||
		ISelect<Topic> select => g.mysql.Select<Topic>();
 | 
							ISelect<Topic> select => g.mysql.Select<Topic>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[Table(Name = "tb_topic")]
 | 
							[Table(Name = "tb_topic")]
 | 
				
			||||||
		class Topic {
 | 
							public class Topic {
 | 
				
			||||||
			[Column(IsIdentity = true, IsPrimary = true)]
 | 
								[Column(IsIdentity = true, IsPrimary = true)]
 | 
				
			||||||
			public int Id { get; set; }
 | 
								public int Id { get; set; }
 | 
				
			||||||
			public int Clicks { get; set; }
 | 
								public int Clicks { get; set; }
 | 
				
			||||||
			public int TestTypeInfoGuid { get; set; }
 | 
								public int TestTypeInfoGuid { get; set; }
 | 
				
			||||||
			public TestTypeInfo Type { get; set; }
 | 
					
 | 
				
			||||||
 | 
								public int TypeGuid { get; set; }
 | 
				
			||||||
 | 
								public virtual TestTypeInfo Type { get; set; }
 | 
				
			||||||
			public string Title { get; set; }
 | 
								public string Title { get; set; }
 | 
				
			||||||
			public DateTime CreateTime { get; set; }
 | 
								public DateTime CreateTime { get; set; }
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		class TestTypeInfo {
 | 
							public class TestTypeInfo {
 | 
				
			||||||
 | 
								[Column(IsIdentity = true)]
 | 
				
			||||||
			public int Guid { get; set; }
 | 
								public int Guid { get; set; }
 | 
				
			||||||
			public int ParentId { get; set; }
 | 
								public int ParentId { get; set; }
 | 
				
			||||||
			public TestTypeParentInfo Parent { get; set; }
 | 
								public TestTypeParentInfo Parent { get; set; }
 | 
				
			||||||
			public string Name { get; set; }
 | 
								public string Name { get; set; }
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		class TestTypeParentInfo {
 | 
							public class TestTypeParentInfo {
 | 
				
			||||||
 | 
								[Column(IsIdentity = true)]
 | 
				
			||||||
			public int Id { get; set; }
 | 
								public int Id { get; set; }
 | 
				
			||||||
			public string Name { get; set; }
 | 
								public string Name { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			public List<TestTypeInfo> Types { get; set; }
 | 
								public List<TestTypeInfo> Types { get; set; }
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[Fact]
 | 
				
			||||||
 | 
							public void Lazy() {
 | 
				
			||||||
 | 
								Topic t = g.mysql.Select<Topic>(2).ToOne();
 | 
				
			||||||
 | 
								Topic tz = g.mysql.Select<Topic>(2).ToOne();
 | 
				
			||||||
 | 
								var tzType = tz.Type;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[Fact]
 | 
							[Fact]
 | 
				
			||||||
		public void ToList() {
 | 
							public void ToList() {
 | 
				
			||||||
			var t0 = select.Limit(50).ToList();
 | 
								var t0 = select.Limit(50).ToList();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Diagnostics;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -11,7 +12,7 @@ public class g {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		.UseMonitorCommand(
 | 
							.UseMonitorCommand(
 | 
				
			||||||
			cmd => {
 | 
								cmd => {
 | 
				
			||||||
				Console.WriteLine(cmd.CommandText);
 | 
									Trace.WriteLine(cmd.CommandText);
 | 
				
			||||||
			}, //监听SQL命令对象,在执行前
 | 
								}, //监听SQL命令对象,在执行前
 | 
				
			||||||
			(cmd, traceLog) => {
 | 
								(cmd, traceLog) => {
 | 
				
			||||||
				Console.WriteLine(traceLog);
 | 
									Console.WriteLine(traceLog);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ namespace FreeSql {
 | 
				
			|||||||
		string[] _slaveConnectionString;
 | 
							string[] _slaveConnectionString;
 | 
				
			||||||
		bool _isAutoSyncStructure = false;
 | 
							bool _isAutoSyncStructure = false;
 | 
				
			||||||
		bool _isSyncStructureToLower = false;
 | 
							bool _isSyncStructureToLower = false;
 | 
				
			||||||
 | 
							bool _isLazyLoading = false;
 | 
				
			||||||
		Action<DbCommand> _aopCommandExecuting = null;
 | 
							Action<DbCommand> _aopCommandExecuting = null;
 | 
				
			||||||
		Action<DbCommand, string> _aopCommandExecuted = null;
 | 
							Action<DbCommand, string> _aopCommandExecuted = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,6 +76,15 @@ namespace FreeSql {
 | 
				
			|||||||
			return this;
 | 
								return this;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 延时加载导航属性对象,导航属性需要声明 virtual
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="value"></param>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							public FreeSqlBuilder UseLazyLoading(bool value) {
 | 
				
			||||||
 | 
								_isLazyLoading = value;
 | 
				
			||||||
 | 
								return this;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
		/// 监视数据库命令对象
 | 
							/// 监视数据库命令对象
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="executing">执行前</param>
 | 
							/// <param name="executing">执行前</param>
 | 
				
			||||||
@@ -98,6 +108,7 @@ namespace FreeSql {
 | 
				
			|||||||
			if (ret != null) {
 | 
								if (ret != null) {
 | 
				
			||||||
				ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure;
 | 
									ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure;
 | 
				
			||||||
				ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower;
 | 
									ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower;
 | 
				
			||||||
 | 
									ret.CodeFirst.IsLazyLoading = _isLazyLoading;
 | 
				
			||||||
				var ado = ret.Ado as Internal.CommonProvider.AdoProvider;
 | 
									var ado = ret.Ado as Internal.CommonProvider.AdoProvider;
 | 
				
			||||||
				ado.AopCommandExecuting += _aopCommandExecuting;
 | 
									ado.AopCommandExecuting += _aopCommandExecuting;
 | 
				
			||||||
				ado.AopCommandExecuted += _aopCommandExecuted;
 | 
									ado.AopCommandExecuted += _aopCommandExecuted;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -544,8 +544,7 @@ return rTn;");
 | 
				
			|||||||
			var type = assemly.DefinedTypes.Where(a => a.FullName.EndsWith(typename)).FirstOrDefault();
 | 
								var type = assemly.DefinedTypes.Where(a => a.FullName.EndsWith(typename)).FirstOrDefault();
 | 
				
			||||||
			return Activator.CreateInstance(type) as ITemplateOutput;
 | 
								return Activator.CreateInstance(type) as ITemplateOutput;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		static ConcurrentDictionary<string, (DateTime, object)> _compiler_objs = new ConcurrentDictionary<string, (DateTime, object)>();
 | 
							internal static Lazy<CSScriptLib.RoslynEvaluator> _compiler = new Lazy<CSScriptLib.RoslynEvaluator>(() => {
 | 
				
			||||||
		static Lazy<CSScriptLib.RoslynEvaluator> _compiler = new Lazy<CSScriptLib.RoslynEvaluator>(() => {
 | 
					 | 
				
			||||||
			var dlls = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName, "*.dll");
 | 
								var dlls = Directory.GetFiles(Directory.GetParent(Type.GetType("IFreeSql, FreeSql").Assembly.Location).FullName, "*.dll");
 | 
				
			||||||
			var compiler = new CSScriptLib.RoslynEvaluator();
 | 
								var compiler = new CSScriptLib.RoslynEvaluator();
 | 
				
			||||||
			compiler.DisableReferencingFromCode = false;
 | 
								compiler.DisableReferencingFromCode = false;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,10 @@ namespace FreeSql {
 | 
				
			|||||||
		/// 转小写同步结构
 | 
							/// 转小写同步结构
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		bool IsSyncStructureToLower { get; set; }
 | 
							bool IsSyncStructureToLower { get; set; }
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 延时加载导航属性对象,导航属性需要声明 virtual
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							bool IsLazyLoading { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 将实体类型与数据库对比,返回DDL语句
 | 
							/// 将实体类型与数据库对比,返回DDL语句
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -249,9 +249,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			public Func<DbDataReader, T1> Read { get; set; }
 | 
								public Func<DbDataReader, T1> Read { get; set; }
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTree() {
 | 
							protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTree() {
 | 
				
			||||||
			var key = string.Join("+", _tables.Select(a => $"{a.Table.DbName}-{a.Alias}"));
 | 
								return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{a.Table.DbName}-{a.Alias}")), s => {
 | 
				
			||||||
			return _dicGetAllFieldExpressionTree.GetOrAdd(key, s => {
 | 
									var tb1 = _tables.First().Table;
 | 
				
			||||||
				var type = _tables.First().Table.Type;
 | 
									var type = tb1.TypeLazy ?? tb1.Type;
 | 
				
			||||||
 | 
									var props = tb1.Properties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				var rowExp = Expression.Parameter(typeof(DbDataReader), "row");
 | 
									var rowExp = Expression.Parameter(typeof(DbDataReader), "row");
 | 
				
			||||||
				var returnTarget = Expression.Label(type);
 | 
									var returnTarget = Expression.Label(type);
 | 
				
			||||||
@@ -266,14 +267,14 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
					Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))),
 | 
										Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))),
 | 
				
			||||||
					Expression.Assign(dataIndexExp, Expression.Constant(0))
 | 
										Expression.Assign(dataIndexExp, Expression.Constant(0))
 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
 | 
									//typeof(Topic).GetMethod("get_Type").IsVirtual
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				var field = new StringBuilder();
 | 
									var field = new StringBuilder();
 | 
				
			||||||
				var dicfield = new Dictionary<string, bool>();
 | 
									var dicfield = new Dictionary<string, bool>();
 | 
				
			||||||
				var tb = _tables.First();
 | 
									var tb = _tables.First();
 | 
				
			||||||
				var index = 0;
 | 
									var index = 0;
 | 
				
			||||||
				var otherindex = 0;
 | 
									var otherindex = 0;
 | 
				
			||||||
				var ps = _tables.First().Table.Properties;
 | 
									foreach (var prop in props.Values) {
 | 
				
			||||||
				foreach (var prop in ps.Values) {
 | 
					 | 
				
			||||||
					if (tb.Table.ColumnsByCs.TryGetValue(prop.Name, out var col)) { //普通字段
 | 
										if (tb.Table.ColumnsByCs.TryGetValue(prop.Name, out var col)) { //普通字段
 | 
				
			||||||
						if (index > 0) field.Append(", ");
 | 
											if (index > 0) field.Append(", ");
 | 
				
			||||||
						var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
 | 
											var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
 | 
				
			||||||
@@ -283,7 +284,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
						else dicfield.Add(quoteName, true);
 | 
											else dicfield.Add(quoteName, true);
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
						var tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType && a.Alias.Contains(prop.Name)).FirstOrDefault();
 | 
											var tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType && a.Alias.Contains(prop.Name)).FirstOrDefault();
 | 
				
			||||||
						if (tb2 == null && ps.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType).FirstOrDefault();
 | 
											if (tb2 == null && props.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType).FirstOrDefault();
 | 
				
			||||||
						if (tb2 == null) continue;
 | 
											if (tb2 == null) continue;
 | 
				
			||||||
						foreach (var col2 in tb2.Table.Columns.Values) {
 | 
											foreach (var col2 in tb2.Table.Columns.Values) {
 | 
				
			||||||
							if (index > 0) field.Append(", ");
 | 
												if (index > 0) field.Append(", ");
 | 
				
			||||||
@@ -333,6 +334,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
						Expression.Assign(retExp, Expression.Convert(readExpValue, type))
 | 
											Expression.Assign(retExp, Expression.Convert(readExpValue, type))
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									if (tb1.TypeLazy != null) blockExp.Add(Expression.Call(retExp, tb1.TypeLazySetOrm, Expression.Constant(_orm))); //将 orm 传递给 lazy
 | 
				
			||||||
				blockExp.AddRange(new Expression[] {
 | 
									blockExp.AddRange(new Expression[] {
 | 
				
			||||||
					Expression.Return(returnTarget, retExp),
 | 
										Expression.Return(returnTarget, retExp),
 | 
				
			||||||
					Expression.Label(returnTarget, Expression.Default(type))
 | 
										Expression.Label(returnTarget, Expression.Default(type))
 | 
				
			||||||
@@ -344,7 +346,8 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection() {
 | 
							protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection() {
 | 
				
			||||||
			var type = _tables.First().Table.Type;
 | 
								var tb1 = _tables.First().Table;
 | 
				
			||||||
 | 
								var type = tb1.Type;
 | 
				
			||||||
			var constructor = _dicConstructor.GetOrAdd(type, s => type.GetConstructor(new Type[0]));
 | 
								var constructor = _dicConstructor.GetOrAdd(type, s => type.GetConstructor(new Type[0]));
 | 
				
			||||||
			var map = new ReadAnonymousTypeInfo { Consturctor = constructor, ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties };
 | 
								var map = new ReadAnonymousTypeInfo { Consturctor = constructor, ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -352,7 +355,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			var dicfield = new Dictionary<string, bool>();
 | 
								var dicfield = new Dictionary<string, bool>();
 | 
				
			||||||
			var tb = _tables.First();
 | 
								var tb = _tables.First();
 | 
				
			||||||
			var index = 0;
 | 
								var index = 0;
 | 
				
			||||||
			var ps = _tables.First().Table.Properties;
 | 
								var ps = tb1.Properties;
 | 
				
			||||||
			foreach (var p in ps.Values) {
 | 
								foreach (var p in ps.Values) {
 | 
				
			||||||
				var child = new ReadAnonymousTypeInfo { Property = p, CsName = p.Name };
 | 
									var child = new ReadAnonymousTypeInfo { Property = p, CsName = p.Name };
 | 
				
			||||||
				if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) { //普通字段
 | 
									if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) { //普通字段
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,9 +22,14 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
		internal abstract string QuoteReadColumn(Type type, string columnName);
 | 
							internal abstract string QuoteReadColumn(Type type, string columnName);
 | 
				
			||||||
		internal abstract string DbName { get; }
 | 
							internal abstract string DbName { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal ICodeFirst CodeFirst { get; set; }
 | 
							internal IFreeSql _orm { get; set; }
 | 
				
			||||||
 | 
							internal ICodeFirst CodeFirst => _orm.CodeFirst;
 | 
				
			||||||
		internal TableInfo GetTableByEntity(Type entity) => Utils.GetTableByEntity(entity, this);
 | 
							internal TableInfo GetTableByEntity(Type entity) => Utils.GetTableByEntity(entity, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public CommonUtils(IFreeSql orm) {
 | 
				
			||||||
 | 
								_orm = orm;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal string WhereObject(TableInfo table, string aliasAndDot, object dywhere) {
 | 
							internal string WhereObject(TableInfo table, string aliasAndDot, object dywhere) {
 | 
				
			||||||
			if (dywhere == null) return "";
 | 
								if (dywhere == null) return "";
 | 
				
			||||||
			var type = dywhere.GetType();
 | 
								var type = dywhere.GetType();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,8 @@ using System.Reflection;
 | 
				
			|||||||
namespace FreeSql.Internal.Model {
 | 
					namespace FreeSql.Internal.Model {
 | 
				
			||||||
	class TableInfo {
 | 
						class TableInfo {
 | 
				
			||||||
		public Type Type { get; set; }
 | 
							public Type Type { get; set; }
 | 
				
			||||||
 | 
							public Type TypeLazy { get; set; }
 | 
				
			||||||
 | 
							public MethodInfo TypeLazySetOrm { get; set; }
 | 
				
			||||||
		public Dictionary<string, PropertyInfo> Properties { get; set; } = new Dictionary<string, PropertyInfo>(StringComparer.CurrentCultureIgnoreCase);
 | 
							public Dictionary<string, PropertyInfo> Properties { get; set; } = new Dictionary<string, PropertyInfo>(StringComparer.CurrentCultureIgnoreCase);
 | 
				
			||||||
		public Dictionary<string, ColumnInfo> Columns { get; set; } = new Dictionary<string, ColumnInfo>(StringComparer.CurrentCultureIgnoreCase);
 | 
							public Dictionary<string, ColumnInfo> Columns { get; set; } = new Dictionary<string, ColumnInfo>(StringComparer.CurrentCultureIgnoreCase);
 | 
				
			||||||
		public Dictionary<string, ColumnInfo> ColumnsByCs { get; set; } = new Dictionary<string, ColumnInfo>(StringComparer.CurrentCultureIgnoreCase);
 | 
							public Dictionary<string, ColumnInfo> ColumnsByCs { get; set; } = new Dictionary<string, ColumnInfo>(StringComparer.CurrentCultureIgnoreCase);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,21 +10,23 @@ using System.Collections.Generic;
 | 
				
			|||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
using System.Data.Common;
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Diagnostics;
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Linq.Expressions;
 | 
					using System.Linq.Expressions;
 | 
				
			||||||
using System.Net;
 | 
					using System.Net;
 | 
				
			||||||
using System.Net.NetworkInformation;
 | 
					using System.Net.NetworkInformation;
 | 
				
			||||||
using System.Reflection;
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
using System.Text.RegularExpressions;
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
using System.Threading;
 | 
					using System.Threading;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.Internal {
 | 
					namespace FreeSql.Internal {
 | 
				
			||||||
	class Utils {
 | 
						class Utils {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static ConcurrentDictionary<string, TableInfo> _cacheGetTableByEntity = new ConcurrentDictionary<string, TableInfo>();
 | 
							static ConcurrentDictionary<string, ConcurrentDictionary<Type, TableInfo>> _cacheGetTableByEntity = new ConcurrentDictionary<string, ConcurrentDictionary<Type, TableInfo>>();
 | 
				
			||||||
		internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
 | 
							internal static TableInfo GetTableByEntity(Type entity, CommonUtils common) {
 | 
				
			||||||
			if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
 | 
								if (entity.FullName.StartsWith("<>f__AnonymousType")) return null;
 | 
				
			||||||
			return _cacheGetTableByEntity.GetOrAdd($"{common.DbName}-{entity.FullName}", key => { //区分数据库类型缓存
 | 
								return _cacheGetTableByEntity.GetOrAdd(common.DbName, k1 => new ConcurrentDictionary<Type, TableInfo>()).GetOrAdd(entity, k2 => { //区分数据库类型缓存
 | 
				
			||||||
				if (common.CodeFirst.GetDbInfo(entity) != null) return null;
 | 
									if (common.CodeFirst.GetDbInfo(entity) != null) return null;
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
				var tbattr = entity.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute;
 | 
									var tbattr = entity.GetCustomAttributes(typeof(TableAttribute), false).LastOrDefault() as TableAttribute;
 | 
				
			||||||
@@ -39,11 +41,20 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
					trytb.DbOldName = trytb.DbOldName?.ToLower();
 | 
										trytb.DbOldName = trytb.DbOldName?.ToLower();
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				trytb.SelectFilter = tbattr?.SelectFilter;
 | 
									trytb.SelectFilter = tbattr?.SelectFilter;
 | 
				
			||||||
 | 
									var virtualProps = new List<(PropertyInfo, bool, bool)>();
 | 
				
			||||||
				foreach (var p in trytb.Properties.Values) {
 | 
									foreach (var p in trytb.Properties.Values) {
 | 
				
			||||||
					var tp = common.CodeFirst.GetDbInfo(p.PropertyType);
 | 
										var tp = common.CodeFirst.GetDbInfo(p.PropertyType);
 | 
				
			||||||
					//if (tp == null) continue;
 | 
										//if (tp == null) continue;
 | 
				
			||||||
					var colattr = p.GetCustomAttributes(typeof(ColumnAttribute), false).LastOrDefault() as ColumnAttribute;
 | 
										var colattr = p.GetCustomAttributes(typeof(ColumnAttribute), false).LastOrDefault() as ColumnAttribute;
 | 
				
			||||||
					if (tp == null && colattr == null) continue;
 | 
										if (tp == null && colattr == null) {
 | 
				
			||||||
 | 
											if (common.CodeFirst.IsLazyLoading) {
 | 
				
			||||||
 | 
												var getIsVirtual = trytb.Type.GetMethod($"get_{p.Name}")?.IsVirtual;
 | 
				
			||||||
 | 
												var setIsVirtual = trytb.Type.GetMethod($"set_{p.Name}")?.IsVirtual;
 | 
				
			||||||
 | 
												if (getIsVirtual == true || setIsVirtual == true)
 | 
				
			||||||
 | 
													virtualProps.Add((p, getIsVirtual == true, setIsVirtual == true));
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											continue;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
					if (colattr == null)
 | 
										if (colattr == null)
 | 
				
			||||||
						colattr = new ColumnAttribute {
 | 
											colattr = new ColumnAttribute {
 | 
				
			||||||
							Name = p.Name,
 | 
												Name = p.Name,
 | 
				
			||||||
@@ -93,7 +104,66 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
					foreach (var col in trytb.Primarys)
 | 
										foreach (var col in trytb.Primarys)
 | 
				
			||||||
						col.Attribute.IsPrimary = true;
 | 
											col.Attribute.IsPrimary = true;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				_cacheGetTableByEntity.TryAdd(entity.FullName, trytb);
 | 
					
 | 
				
			||||||
 | 
									if (common.CodeFirst.IsLazyLoading && virtualProps.Any()) {
 | 
				
			||||||
 | 
										//virtual 属性延时加载,生态产生新的重写类
 | 
				
			||||||
 | 
										if (trytb.Type.IsNotPublic) throw new Exception("【延时加载】功能发生错误,实体类必须声明为 public");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										var overrieds = 0;
 | 
				
			||||||
 | 
										var cscode = new StringBuilder();
 | 
				
			||||||
 | 
										cscode.AppendLine("using System;")
 | 
				
			||||||
 | 
											.AppendLine("using FreeSql.DataAnnotations;")
 | 
				
			||||||
 | 
											.AppendLine("using System.Collections.Generic;")
 | 
				
			||||||
 | 
											.AppendLine("using System.Linq;")
 | 
				
			||||||
 | 
											.AppendLine("")
 | 
				
			||||||
 | 
											.Append("public class FreeSqlOverrideLazyEntity").Append(trytb.Type.Name).Append(" : ").Append(trytb.Type.FullName.Replace("+", ".")).AppendLine(" {")
 | 
				
			||||||
 | 
											.AppendLine("	public IFreeSql __fsql_orm__ { get; set; }\r\n");
 | 
				
			||||||
 | 
										foreach(var vp in virtualProps) {
 | 
				
			||||||
 | 
											TableInfo pktb = null;
 | 
				
			||||||
 | 
											if (vp.Item1.PropertyType == trytb.Type) pktb = trytb;
 | 
				
			||||||
 | 
											else pktb = GetTableByEntity(vp.Item1.PropertyType, common);
 | 
				
			||||||
 | 
											if (pktb == null || pktb.Primarys.Any() == false) {
 | 
				
			||||||
 | 
												//continue;
 | 
				
			||||||
 | 
												throw new Exception($"【延时加载】功能发生错误,导航属性 {trytb.Type.FullName}.{vp.Item1.Name} 类型不正确,或者实体类型 {vp.Item1.PropertyType.FullName} 缺少主键标识");
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											var lmbdWhere = new StringBuilder();
 | 
				
			||||||
 | 
											var vpcols = new ColumnInfo[pktb.Primarys.Length];
 | 
				
			||||||
 | 
											for (var a = 0; a < pktb.Primarys.Length; a++) {
 | 
				
			||||||
 | 
												if (trytb.ColumnsByCs.TryGetValue($"{vp.Item1.Name}{pktb.Primarys[a].CsName}", out var trycol) == false && //骆峰命名
 | 
				
			||||||
 | 
													trytb.ColumnsByCs.TryGetValue($"{vp.Item1.Name}_{pktb.Primarys[a].CsName}", out trycol) == false //下划线命名
 | 
				
			||||||
 | 
													) {
 | 
				
			||||||
 | 
													pktb = null;
 | 
				
			||||||
 | 
													throw new Exception($"【延时加载】功能发生错误,导航属性 {trytb.Type.FullName}.{vp.Item1.Name} 没有找到对应的字段 {vp.Item1.Name}{pktb.Primarys[a].CsName} 或 {vp.Item1.Name}_{pktb.Primarys[a].CsName}");
 | 
				
			||||||
 | 
													//break;
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
												if (a > 0) lmbdWhere.Append(" && ");
 | 
				
			||||||
 | 
												lmbdWhere.Append("a.").Append(pktb.Primarys[a].CsName).Append(" == this.").Append(trycol.CsName);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											if (pktb == null) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											cscode.Append("	public override ").Append(vp.Item1.PropertyType.FullName.Replace("+", ".")).Append(" ").Append(vp.Item1.Name).AppendLine(" {");
 | 
				
			||||||
 | 
											if (vp.Item2) { //get 重写
 | 
				
			||||||
 | 
												cscode.Append("		get => base.").Append(vp.Item1.Name)
 | 
				
			||||||
 | 
													.Append(" ?? (base.").Append(vp.Item1.Name)
 | 
				
			||||||
 | 
													.Append(" = __fsql_orm__.Select<").Append(vp.Item1.PropertyType.FullName.Replace("+", ".")).Append(">().Where(a => ")
 | 
				
			||||||
 | 
													.Append(lmbdWhere.ToString())
 | 
				
			||||||
 | 
													.Append(").ToOne()").AppendLine(");");
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											if (vp.Item3) { //set 重写
 | 
				
			||||||
 | 
												cscode.Append("		set => base.").Append(vp.Item1.Name).AppendLine(" = value;");
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											cscode.AppendLine("	}");
 | 
				
			||||||
 | 
											++overrieds;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (overrieds > 0) {
 | 
				
			||||||
 | 
											cscode.AppendLine("}");
 | 
				
			||||||
 | 
											var assemly = Generator.TemplateEngin._compiler.Value.CompileCode(cscode.ToString());
 | 
				
			||||||
 | 
											var type = assemly.DefinedTypes.Where(a => a.FullName.EndsWith($"FreeSqlOverrideLazyEntity{trytb.Type.Name}")).FirstOrDefault();
 | 
				
			||||||
 | 
											trytb.TypeLazy = type;
 | 
				
			||||||
 | 
											trytb.TypeLazySetOrm = type.GetProperty("__fsql_orm__").GetSetMethod();
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				return trytb;
 | 
									return trytb;
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@ namespace FreeSql.MySql {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		public bool IsAutoSyncStructure { get; set; } = true;
 | 
							public bool IsAutoSyncStructure { get; set; } = true;
 | 
				
			||||||
		public bool IsSyncStructureToLower { get; set; } = false;
 | 
							public bool IsSyncStructureToLower { get; set; } = false;
 | 
				
			||||||
 | 
							public bool IsLazyLoading { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static object _dicCsToDbLock = new object();
 | 
							static object _dicCsToDbLock = new object();
 | 
				
			||||||
		static Dictionary<string, (MySqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (MySqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
 | 
							static Dictionary<string, (MySqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (MySqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@ namespace FreeSql.MySql {
 | 
				
			|||||||
			this.Ado = new MySqlAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
 | 
								this.Ado = new MySqlAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.DbFirst = new MySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
								this.DbFirst = new MySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
			this.InternalCommonUtils.CodeFirst = this.CodeFirst = new MySqlCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
								this.CodeFirst = new MySqlCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal CommonUtils InternalCommonUtils { get; }
 | 
							internal CommonUtils InternalCommonUtils { get; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,10 +8,7 @@ using System.Data.Common;
 | 
				
			|||||||
namespace FreeSql.MySql {
 | 
					namespace FreeSql.MySql {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class MySqlUtils : CommonUtils {
 | 
						class MySqlUtils : CommonUtils {
 | 
				
			||||||
		IFreeSql _orm;
 | 
							public MySqlUtils(IFreeSql orm) : base(orm) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
		public MySqlUtils(IFreeSql orm) {
 | 
					 | 
				
			||||||
			_orm = orm;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
							internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		public bool IsAutoSyncStructure { get; set; } = true;
 | 
							public bool IsAutoSyncStructure { get; set; } = true;
 | 
				
			||||||
		public bool IsSyncStructureToLower { get; set; } = false;
 | 
							public bool IsSyncStructureToLower { get; set; } = false;
 | 
				
			||||||
 | 
							public bool IsLazyLoading { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static object _dicCsToDbLock = new object();
 | 
							static object _dicCsToDbLock = new object();
 | 
				
			||||||
		static Dictionary<string, (OracleDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (OracleDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
 | 
							static Dictionary<string, (OracleDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (OracleDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ namespace FreeSql.Oracle {
 | 
				
			|||||||
			this.Cache = new CacheProvider(cache, log);
 | 
								this.Cache = new CacheProvider(cache, log);
 | 
				
			||||||
			this.Ado = new OracleAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
 | 
								this.Ado = new OracleAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.InternalCommonUtils.CodeFirst = this.CodeFirst = new OracleCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
								this.CodeFirst = new OracleCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal CommonUtils InternalCommonUtils { get; }
 | 
							internal CommonUtils InternalCommonUtils { get; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,9 +8,7 @@ using System.Data.Common;
 | 
				
			|||||||
namespace FreeSql.Oracle {
 | 
					namespace FreeSql.Oracle {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class OracleUtils : CommonUtils {
 | 
						class OracleUtils : CommonUtils {
 | 
				
			||||||
		IFreeSql _orm;
 | 
							public OracleUtils(IFreeSql orm) : base(orm) {
 | 
				
			||||||
		public OracleUtils(IFreeSql orm) {
 | 
					 | 
				
			||||||
			_orm = orm;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
							internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,6 +29,7 @@ namespace FreeSql.PostgreSQL {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		public bool IsAutoSyncStructure { get; set; } = true;
 | 
							public bool IsAutoSyncStructure { get; set; } = true;
 | 
				
			||||||
		public bool IsSyncStructureToLower { get; set; } = false;
 | 
							public bool IsSyncStructureToLower { get; set; } = false;
 | 
				
			||||||
 | 
							public bool IsLazyLoading { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static object _dicCsToDbLock = new object();
 | 
							static object _dicCsToDbLock = new object();
 | 
				
			||||||
		static Dictionary<string, (NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
 | 
							static Dictionary<string, (NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (NpgsqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@ namespace FreeSql.PostgreSQL {
 | 
				
			|||||||
			this.Ado = new PostgreSQLAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
 | 
								this.Ado = new PostgreSQLAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.DbFirst = new PostgreSQLDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
								this.DbFirst = new PostgreSQLDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
			this.InternalCommonUtils.CodeFirst = this.CodeFirst = new PostgreSQLCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
								this.CodeFirst = new PostgreSQLCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal CommonUtils InternalCommonUtils { get; }
 | 
							internal CommonUtils InternalCommonUtils { get; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,9 +11,7 @@ using System.Net;
 | 
				
			|||||||
namespace FreeSql.PostgreSQL {
 | 
					namespace FreeSql.PostgreSQL {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class PostgreSQLUtils : CommonUtils {
 | 
						class PostgreSQLUtils : CommonUtils {
 | 
				
			||||||
		IFreeSql _orm;
 | 
							public PostgreSQLUtils(IFreeSql orm) : base(orm) {
 | 
				
			||||||
		public PostgreSQLUtils(IFreeSql orm) {
 | 
					 | 
				
			||||||
			_orm = orm;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static Array getParamterArrayValue(Type arrayType, object value, object defaultValue) {
 | 
							static Array getParamterArrayValue(Type arrayType, object value, object defaultValue) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,7 @@ namespace FreeSql.SqlServer {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		public bool IsAutoSyncStructure { get; set; } = true;
 | 
							public bool IsAutoSyncStructure { get; set; } = true;
 | 
				
			||||||
		public bool IsSyncStructureToLower { get; set; } = false;
 | 
							public bool IsSyncStructureToLower { get; set; } = false;
 | 
				
			||||||
 | 
							public bool IsLazyLoading { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static object _dicCsToDbLock = new object();
 | 
							static object _dicCsToDbLock = new object();
 | 
				
			||||||
		static Dictionary<string, (SqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (SqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
 | 
							static Dictionary<string, (SqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (SqlDbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ namespace FreeSql.SqlServer {
 | 
				
			|||||||
			this.Ado = new SqlServerAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
 | 
								this.Ado = new SqlServerAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.DbFirst = new SqlServerDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
								this.DbFirst = new SqlServerDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
			this.InternalCommonUtils.CodeFirst = this.CodeFirst = new SqlServerCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
								this.CodeFirst = new SqlServerCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal CommonUtils InternalCommonUtils { get; }
 | 
							internal CommonUtils InternalCommonUtils { get; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,9 +8,7 @@ using System.Data.SqlClient;
 | 
				
			|||||||
namespace FreeSql.SqlServer {
 | 
					namespace FreeSql.SqlServer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class SqlServerUtils : CommonUtils {
 | 
						class SqlServerUtils : CommonUtils {
 | 
				
			||||||
		IFreeSql _orm;
 | 
							public SqlServerUtils(IFreeSql orm) : base(orm) {
 | 
				
			||||||
		public SqlServerUtils(IFreeSql orm) {
 | 
					 | 
				
			||||||
			_orm = orm;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
							internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,7 @@ namespace FreeSql.Sqlite {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		public bool IsAutoSyncStructure { get; set; } = true;
 | 
							public bool IsAutoSyncStructure { get; set; } = true;
 | 
				
			||||||
		public bool IsSyncStructureToLower { get; set; } = false;
 | 
							public bool IsSyncStructureToLower { get; set; } = false;
 | 
				
			||||||
 | 
							public bool IsLazyLoading { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static object _dicCsToDbLock = new object();
 | 
							static object _dicCsToDbLock = new object();
 | 
				
			||||||
		static Dictionary<string, (DbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (DbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
 | 
							static Dictionary<string, (DbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)> _dicCsToDb = new Dictionary<string, (DbType type, string dbtype, string dbtypeFull, bool? isUnsigned, bool? isnullable, object defaultValue)>() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ namespace FreeSql.Sqlite {
 | 
				
			|||||||
			this.Cache = new CacheProvider(cache, log);
 | 
								this.Cache = new CacheProvider(cache, log);
 | 
				
			||||||
			this.Ado = new SqliteAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
 | 
								this.Ado = new SqliteAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.InternalCommonUtils.CodeFirst = this.CodeFirst = new SqliteCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
								this.CodeFirst = new SqliteCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal CommonUtils InternalCommonUtils { get; }
 | 
							internal CommonUtils InternalCommonUtils { get; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,9 +9,7 @@ using System.Data.SQLite;
 | 
				
			|||||||
namespace FreeSql.Sqlite {
 | 
					namespace FreeSql.Sqlite {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class SqliteUtils : CommonUtils {
 | 
						class SqliteUtils : CommonUtils {
 | 
				
			||||||
		IFreeSql _orm;
 | 
							public SqliteUtils(IFreeSql orm) : base(orm) {
 | 
				
			||||||
		public SqliteUtils(IFreeSql orm) {
 | 
					 | 
				
			||||||
			_orm = orm;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
							internal override DbParameter AppendParamter(List<DbParameter> _params, string parameterName, Type type, object value) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,6 +31,8 @@ IFreeSql fsql = new FreeSql.FreeSqlBuilder()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    .UseAutoSyncStructure(true) //自动同步实体结构到数据库
 | 
					    .UseAutoSyncStructure(true) //自动同步实体结构到数据库
 | 
				
			||||||
    .UseSyncStructureToLower(true) //转小写同步结构
 | 
					    .UseSyncStructureToLower(true) //转小写同步结构
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.UseLazyLoading(true) //延时加载导航属性对象,导航属性需要声明 virtual
 | 
				
			||||||
    .Build();
 | 
					    .Build();
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user