mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
完成延时加载开发与测试,ICollection集合待支持
This commit is contained in:
parent
56d79c9696
commit
a7896007a9
@ -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,23 +10,25 @@ 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;
|
||||||
var trytb = new TableInfo();
|
var trytb = new TableInfo();
|
||||||
trytb.Type = entity;
|
trytb.Type = entity;
|
||||||
@ -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();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user