mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 10:42:52 +08:00
- 修复 导航属性配置,循环关系的情况下可能导致的 bug;
This commit is contained in:
parent
ef18b61e84
commit
96796106d5
@ -246,7 +246,6 @@ namespace FreeSql.Internal
|
||||
#region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类
|
||||
var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.Name}";
|
||||
var trytbTypeLazyName = default(string);
|
||||
var overrieds = 0;
|
||||
StringBuilder cscode = null;
|
||||
if (common.CodeFirst.IsLazyLoading && propsLazy.Any())
|
||||
{
|
||||
@ -265,10 +264,39 @@ namespace FreeSql.Internal
|
||||
.AppendLine(" [JsonIgnore] private IFreeSql __fsql_orm__ { get; set; }\r\n");
|
||||
}
|
||||
|
||||
var cscodeLength = cscode?.Length ?? 0;
|
||||
foreach (var pnv in propsNavObjs)
|
||||
{
|
||||
var vp = propsLazy.Where(a => a.Item1 == pnv).FirstOrDefault();
|
||||
var isLazy = vp.Item1 != null && !string.IsNullOrEmpty(trytbTypeLazyName);
|
||||
|
||||
AddTableRef(common, trytb, pnv, isLazy, vp, cscode);
|
||||
}
|
||||
if (cscode?.Length > cscodeLength)
|
||||
{
|
||||
cscode.AppendLine("}");
|
||||
Assembly assembly = null;
|
||||
if (MethodLazyLoadingComplier.Value == null) throw new Exception("【延时加载】功能需要安装 FreeSql.Extensions.LazyLoading.dll,可前往 nuget 下载");
|
||||
try
|
||||
{
|
||||
assembly = MethodLazyLoadingComplier.Value.Invoke(null, new object[] { cscode.ToString() }) as Assembly;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"【延时加载】{trytbTypeName} 编译错误:{ex.Message}\r\n\r\n{cscode}");
|
||||
}
|
||||
var type = assembly.DefinedTypes.Where(a => a.FullName.EndsWith(trytbTypeLazyName)).FirstOrDefault();
|
||||
trytb.TypeLazy = type;
|
||||
trytb.TypeLazySetOrm = type.GetProperty("__fsql_orm__", BindingFlags.Instance | BindingFlags.NonPublic).GetSetMethod(true);
|
||||
tbc.AddOrUpdate(type, trytb, (oldkey, oldval) => trytb);
|
||||
}
|
||||
#endregion
|
||||
|
||||
return tbc.TryGetValue(entity, out var trytb2) ? trytb2 : trytb;
|
||||
}
|
||||
public static void AddTableRef(CommonUtils common, TableInfo trytb, PropertyInfo pnv, bool isLazy, (PropertyInfo, bool, bool)? vp, StringBuilder cscode)
|
||||
{
|
||||
var trytbTypeName = trytb.Type.IsNested ? $"{trytb.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{trytb.Type.DeclaringType.Name}.{trytb.Type.Name}" : $"{trytb.Type.Namespace?.NotNullAndConcat(".")}{trytb.Type.Name}";
|
||||
var propTypeName = pnv.PropertyType.IsGenericType ?
|
||||
$"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace?.NotNullAndConcat(".")}{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace?.NotNullAndConcat(".")}{a.Name}"))}>" :
|
||||
(pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name}");
|
||||
@ -282,17 +310,17 @@ namespace FreeSql.Internal
|
||||
var propElementType = pnv.PropertyType.GenericTypeArguments.FirstOrDefault() ?? pnv.PropertyType.GetElementType();
|
||||
if (propElementType != null)
|
||||
{
|
||||
if (typeof(IEnumerable).IsAssignableFrom(pnv.PropertyType) == false) continue;
|
||||
if (typeof(IEnumerable).IsAssignableFrom(pnv.PropertyType) == false) return;
|
||||
if (trytb.Primarys.Any() == false)
|
||||
{
|
||||
nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {trytbTypeName} 缺少主键标识,[Column(IsPrimary = true)]");
|
||||
trytb.AddOrUpdateTableRef(pnv.Name, nvref);
|
||||
//if (isLazy) throw nvref.Exception;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
var tbref = propElementType == trytb.Type ? trytb : GetTableByEntity(propElementType, common); //可能是父子关系
|
||||
if (tbref == null) continue;
|
||||
if (tbref == null) return;
|
||||
|
||||
var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace?.NotNullAndConcat(".")}{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace?.NotNullAndConcat(".")}{tbref.Type.Name}";
|
||||
Type midType = null;
|
||||
@ -321,7 +349,7 @@ namespace FreeSql.Internal
|
||||
nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {tbrefTypeName} 必须存在对应的 [Navigate(ManyToMany = x)] 集合属性");
|
||||
trytb.AddOrUpdateTableRef(pnv.Name, nvref);
|
||||
//if (isLazy) throw nvref.Exception;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
if (isManyToMany)
|
||||
{
|
||||
@ -344,7 +372,7 @@ namespace FreeSql.Internal
|
||||
nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {tbrefTypeName} 缺少主键标识,[Column(IsPrimary = true)]");
|
||||
trytb.AddOrUpdateTableRef(pnv.Name, nvref);
|
||||
//if (isLazy) throw nvref.Exception;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
if (pnvAttr?.ManyToMany == null)
|
||||
{
|
||||
@ -432,6 +460,11 @@ namespace FreeSql.Internal
|
||||
try
|
||||
{
|
||||
trytbTf = tbmid.GetTableRef(midTypePropsTrytb.Name, true);
|
||||
if (trytbTf == null)
|
||||
{
|
||||
AddTableRef(common, tbmid, midTypePropsTrytb, false, null, null);
|
||||
trytbTf = tbmid.GetTableRef(midTypePropsTrytb.Name, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -472,6 +505,11 @@ namespace FreeSql.Internal
|
||||
try
|
||||
{
|
||||
tbrefTf = tbmid.GetTableRef(midTypePropsTbref.Name, true);
|
||||
if (tbrefTf == null)
|
||||
{
|
||||
AddTableRef(common, tbmid, midTypePropsTbref, false, null, null);
|
||||
tbrefTf = tbmid.GetTableRef(midTypePropsTbref.Name, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -598,7 +636,7 @@ namespace FreeSql.Internal
|
||||
{
|
||||
cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;")
|
||||
.Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {");
|
||||
if (vp.Item2)
|
||||
if (vp?.Item2 == true)
|
||||
{ //get 重写
|
||||
cscode.Append(" get {\r\n")
|
||||
.Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {");
|
||||
@ -615,7 +653,7 @@ namespace FreeSql.Internal
|
||||
.Append(" return base.").Append(pnv.Name).AppendLine(";")
|
||||
.Append(" }\r\n");
|
||||
}
|
||||
if (vp.Item3)
|
||||
if (vp?.Item3 == true)
|
||||
{ //set 重写
|
||||
cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;");
|
||||
}
|
||||
@ -731,7 +769,7 @@ namespace FreeSql.Internal
|
||||
{
|
||||
cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;")
|
||||
.Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {");
|
||||
if (vp.Item2)
|
||||
if (vp?.Item2 == true)
|
||||
{ //get 重写
|
||||
cscode.Append(" get {\r\n")
|
||||
.Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {");
|
||||
@ -754,7 +792,7 @@ namespace FreeSql.Internal
|
||||
.Append(" return base.").Append(pnv.Name).AppendLine(";")
|
||||
.Append(" }\r\n");
|
||||
}
|
||||
if (vp.Item3)
|
||||
if (vp?.Item3 == true)
|
||||
{ //set 重写
|
||||
cscode.Append(" set => base.").Append(pnv.Name).AppendLine(" = value;");
|
||||
}
|
||||
@ -765,7 +803,7 @@ namespace FreeSql.Internal
|
||||
else
|
||||
{ //一对一、多对一
|
||||
var tbref = pnv.PropertyType == trytb.Type ? trytb : GetTableByEntity(pnv.PropertyType, common); //可能是父子关系
|
||||
if (tbref == null) continue;
|
||||
if (tbref == null) return;
|
||||
if (tbref.Primarys.Any() == false)
|
||||
{
|
||||
nvref.Exception = new Exception($"导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {propTypeName} 缺少主键标识,[Column(IsPrimary = true)]");
|
||||
@ -885,7 +923,7 @@ namespace FreeSql.Internal
|
||||
{
|
||||
cscode.Append(" private bool __lazy__").Append(pnv.Name).AppendLine(" = false;")
|
||||
.Append(" public override ").Append(propTypeName).Append(" ").Append(pnv.Name).AppendLine(" {");
|
||||
if (vp.Item2)
|
||||
if (vp?.Item2 == true)
|
||||
{ //get 重写
|
||||
cscode.Append(" get {\r\n")
|
||||
.Append(" if (base.").Append(pnv.Name).Append(" == null && __lazy__").Append(pnv.Name).AppendLine(" == false) {");
|
||||
@ -901,7 +939,7 @@ namespace FreeSql.Internal
|
||||
.Append(" return base.").Append(pnv.Name).AppendLine(";")
|
||||
.Append(" }\r\n");
|
||||
}
|
||||
if (vp.Item3)
|
||||
if (vp?.Item3 == true)
|
||||
{ //set 重写
|
||||
cscode.Append(" set {\r\n")
|
||||
.Append(" base.").Append(pnv.Name).AppendLine(" = value;")
|
||||
@ -911,30 +949,6 @@ namespace FreeSql.Internal
|
||||
cscode.AppendLine(" }");
|
||||
}
|
||||
}
|
||||
|
||||
if (isLazy) ++overrieds;
|
||||
}
|
||||
if (overrieds > 0)
|
||||
{
|
||||
cscode.AppendLine("}");
|
||||
Assembly assembly = null;
|
||||
if (MethodLazyLoadingComplier.Value == null) throw new Exception("【延时加载】功能需要安装 FreeSql.Extensions.LazyLoading.dll,可前往 nuget 下载");
|
||||
try
|
||||
{
|
||||
assembly = MethodLazyLoadingComplier.Value.Invoke(null, new object[] { cscode.ToString() }) as Assembly;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"【延时加载】{trytbTypeName} 编译错误:{ex.Message}\r\n\r\n{cscode}");
|
||||
}
|
||||
var type = assembly.DefinedTypes.Where(a => a.FullName.EndsWith(trytbTypeLazyName)).FirstOrDefault();
|
||||
trytb.TypeLazy = type;
|
||||
trytb.TypeLazySetOrm = type.GetProperty("__fsql_orm__", BindingFlags.Instance | BindingFlags.NonPublic).GetSetMethod(true);
|
||||
tbc.AddOrUpdate(type, trytb, (oldkey, oldval) => trytb);
|
||||
}
|
||||
#endregion
|
||||
|
||||
return tbc.TryGetValue(entity, out var trytb2) ? trytb2 : trytb;
|
||||
}
|
||||
static Lazy<MethodInfo> MethodLazyLoadingComplier = new Lazy<MethodInfo>(() =>
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user