- 补充 Navigate(ManyToMany = typeof(中间表)) 多对多自定义配置;

This commit is contained in:
28810 2019-07-15 18:10:59 +08:00
parent 179b7d9851
commit b62afec7bb
18 changed files with 841 additions and 164 deletions

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.7.8</Version>
<Version>0.7.9</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<Description>FreeSql 扩展包,可实现【延时加载】属性.</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.7.8</Version>
<Version>0.7.9</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.7.8</Version>
<Version>0.7.9</Version>
<Authors>YeXiangQin</Authors>
<Description>FreeSql Implementation of General Repository, Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite, and read/write separation、and split table.</Description>
<PackageProjectUrl>https://github.com/2881099/FreeSql/wiki/Repository</PackageProjectUrl>

View File

@ -0,0 +1,252 @@
using FreeSql.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Threading;
using Xunit;
namespace FreeSql.Tests.DataAnnotations
{
public class ManyToManyTest
{
Random rnd = new Random();
#region
[Fact]
public void Select()
{
var users = new mtm_user[10];
var roles = new mtm_role[10];
var urs = new List<mtm_user_mtm_role>();
for (var a = 0; a < users.Length; a++)
{
var uid = Guid.NewGuid();
users[a] = new mtm_user
{
id = uid,
username = "用户" + a + "_" + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
}
g.sqlite.Insert(users).ExecuteAffrows();
for (var a = 0; a < roles.Length; a++)
{
var uid = Guid.NewGuid();
roles[a] = new mtm_role
{
id = uid,
name = "角色" + a + "_" + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
}
g.sqlite.Insert(roles).ExecuteAffrows();
for (var a = 0; a < users.Length; a++)
{
for (var b = roles.Length; b >= 0; b--)
{
var ur = new mtm_user_mtm_role
{
mtm_user_id = users[a].id,
mtm_role_id = roles[rnd.Next(roles.Length)].id
};
if (urs.Where(c => c.mtm_role_id == ur.mtm_role_id && c.mtm_user_id == ur.mtm_user_id).Any() == false)
urs.Add(ur);
}
}
g.sqlite.Insert(urs.ToArray()).ExecuteAffrows();
var select1 = g.sqlite.Select<mtm_user>().Limit(10).OrderByDescending(a => a.createtime).ToList(true);
var select2 = g.sqlite.Select<mtm_user>().IncludeMany(a => a.mtm_roles).Limit(10).OrderByDescending(a => a.createtime).ToList(true);
}
public class mtm_user
{
public Guid id { get; set; }
public string username { get; set; }
public DateTime createtime { get; set; }
public virtual List<mtm_role> mtm_roles { get; set; }
}
public class mtm_user_mtm_role
{
public Guid mtm_user_id { get; set; }
public Guid mtm_role_id { get; set; }
public mtm_user mtm_user { get; set; }
public mtm_role mtm_role { get; set; }
}
public class mtm_role
{
public Guid id { get; set; }
public string name { get; set; }
public DateTime createtime { get; set; }
public virtual List<mtm_user> mtm_users { get; set; }
}
#endregion
#region
[Fact]
public void Navigate1()
{
var users = new mtm_user_nav1[10];
var roles = new mtm_role_nav1[10];
var urs = new List<user_role_nav1>();
for (var a = 0; a < users.Length; a++)
{
var uid = Guid.NewGuid();
users[a] = new mtm_user_nav1
{
id = uid,
username = "用户" + a + "_" + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
}
g.sqlite.Insert(users).ExecuteAffrows();
for (var a = 0; a < roles.Length; a++)
{
var uid = Guid.NewGuid();
roles[a] = new mtm_role_nav1
{
id = uid,
name = "角色" + a + "_" + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
}
g.sqlite.Insert(roles).ExecuteAffrows();
for (var a = 0; a < users.Length; a++)
{
for (var b = roles.Length; b >= 0; b--)
{
var ur = new user_role_nav1
{
user_id = users[a].id,
role_id = roles[rnd.Next(roles.Length)].id
};
if (urs.Where(c => c.role_id == ur.role_id && c.user_id == ur.user_id).Any() == false)
urs.Add(ur);
}
}
g.sqlite.Insert(urs.ToArray()).ExecuteAffrows();
var select1 = g.sqlite.Select<mtm_user_nav1>().Limit(10).OrderByDescending(a => a.createtime).ToList(true);
var select2 = g.sqlite.Select<mtm_user_nav1>().IncludeMany(a => a.roles).Limit(10).OrderByDescending(a => a.createtime).ToList(true);
}
public class mtm_user_nav1
{
public Guid id { get; set; }
public string username { get; set; }
public DateTime createtime { get; set; }
[Navigate(ManyToMany = typeof(user_role_nav1))]
public virtual List<mtm_role_nav1> roles { get; set; }
}
public class user_role_nav1
{
public Guid user_id { get; set; }
public Guid role_id { get; set; }
public mtm_user_nav1 user { get; set; }
public mtm_role_nav1 role { get; set; }
}
public class mtm_role_nav1
{
public Guid id { get; set; }
public string name { get; set; }
public DateTime createtime { get; set; }
[Navigate(ManyToMany = typeof(user_role_nav1))]
public virtual List<mtm_user_nav1> users { get; set; }
}
#endregion
#region
[Fact]
public void Navigate()
{
var users = new mtm_user_nav[10];
var roles = new mtm_role_nav[10];
var urs = new List<user_role_nav>();
for (var a = 0; a < users.Length; a++)
{
var uid = Guid.NewGuid();
users[a] = new mtm_user_nav
{
id = uid,
username = "用户" + a + "_" + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
}
g.sqlite.Insert(users).ExecuteAffrows();
for (var a = 0; a < roles.Length; a++)
{
var uid = Guid.NewGuid();
roles[a] = new mtm_role_nav
{
id = uid,
name = "角色" + a + "_" + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
}
g.sqlite.Insert(roles).ExecuteAffrows();
for (var a = 0; a < users.Length; a++)
{
for (var b = roles.Length; b >= 0; b--)
{
var ur = new user_role_nav
{
user_pkid = users[a].id,
role_pkid = roles[rnd.Next(roles.Length)].id
};
if (urs.Where(c => c.role_pkid == ur.role_pkid && c.user_pkid == ur.user_pkid).Any() == false)
urs.Add(ur);
}
}
g.sqlite.Insert(urs.ToArray()).ExecuteAffrows();
var select1 = g.sqlite.Select<mtm_user_nav>().Limit(10).OrderByDescending(a => a.createtime).ToList(true);
var select2 = g.sqlite.Select<mtm_user_nav>().IncludeMany(a => a.roles).Limit(10).OrderByDescending(a => a.createtime).ToList(true);
}
public class mtm_user_nav
{
public Guid id { get; set; }
public string username { get; set; }
public DateTime createtime { get; set; }
[Navigate(ManyToMany = typeof(user_role_nav))]
public virtual List<mtm_role_nav> roles { get; set; }
}
public class user_role_nav
{
public Guid user_pkid { get; set; }
public Guid role_pkid { get; set; }
[Navigate("user_pkid")]
public mtm_user_nav user { get; set; }
[Navigate("role_pkid")]
public mtm_role_nav role { get; set; }
}
public class mtm_role_nav
{
public Guid id { get; set; }
public string name { get; set; }
public DateTime createtime { get; set; }
[Navigate(ManyToMany = typeof(user_role_nav))]
public virtual List<mtm_user_nav> users { get; set; }
}
#endregion
}
}

View File

@ -0,0 +1,141 @@
using FreeSql.DataAnnotations;
using System;
using System.Numerics;
using Xunit;
namespace FreeSql.Tests.DataAnnotations
{
public class ManyToOneTest
{
#region
[Fact]
public void Select()
{
var users = new mto_user[10];
var topics = new mto_topic[30];
for (var a = 0; a < users.Length; a++)
{
var uid = Guid.NewGuid();
users[a] = new mto_user
{
id = uid,
username = Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3] = new mto_topic
{
id = Guid.NewGuid(),
userid = uid,
title = "测试标标题" + (a * 3) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3 + 1] = new mto_topic
{
id = Guid.NewGuid(),
userid = uid,
title = "测试标标题" + (a * 3 + 1) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3 + 2] = new mto_topic
{
id = Guid.NewGuid(),
userid = uid,
title = "测试标标题" + (a * 3 + 2) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
}
g.sqlite.Insert(users).ExecuteAffrows();
g.sqlite.Insert(topics).ExecuteAffrows();
var select1 = g.sqlite.Select<mto_topic>().Limit(30).OrderByDescending(a => a.createtime).ToList(true);
var select2 = g.sqlite.Select<mto_topic>().Include(a => a.user).Limit(30).OrderByDescending(a => a.createtime).ToList(true);
var firstct = users[0].createtime.AddSeconds(-1);
var select3 = g.sqlite.Select<mto_topic>().Where(a => a.user.createtime > firstct).Limit(30).OrderByDescending(a => a.createtime).ToList(true);
}
public class mto_user
{
public Guid id { get; set; }
public string username { get; set; }
public DateTime createtime { get; set; }
}
public class mto_topic
{
public Guid id { get; set; }
public Guid userid { get; set; }
public virtual mto_user user { get; set; }
public string title { get; set; }
public DateTime createtime { get; set; }
}
#endregion
#region
[Fact]
public void Navigate()
{
var users = new mto_user_nav[10];
var topics = new mto_topic_nav[30];
for (var a = 0; a < users.Length; a++)
{
var uid = Guid.NewGuid();
users[a] = new mto_user_nav
{
id = uid,
username = Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3] = new mto_topic_nav
{
id = Guid.NewGuid(),
user_nav_pkid = uid,
title = "测试标标题" + (a * 3) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3 + 1] = new mto_topic_nav
{
id = Guid.NewGuid(),
user_nav_pkid = uid,
title = "测试标标题" + (a * 3 + 1) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3 + 2] = new mto_topic_nav
{
id = Guid.NewGuid(),
user_nav_pkid = uid,
title = "测试标标题" + (a * 3 + 2) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
}
g.sqlite.Insert(users).ExecuteAffrows();
g.sqlite.Insert(topics).ExecuteAffrows();
var select1 = g.sqlite.Select<mto_topic_nav>().Limit(30).OrderByDescending(a => a.createtime).ToList(true);
var select2 = g.sqlite.Select<mto_topic_nav>().Include(a => a.user).Limit(30).OrderByDescending(a => a.createtime).ToList(true);
var firstct = users[0].createtime.AddSeconds(-1);
var select3 = g.sqlite.Select<mto_topic_nav>().Where(a => a.user.createtime > firstct).Limit(30).OrderByDescending(a => a.createtime).ToList(true);
}
public class mto_user_nav
{
public Guid id { get; set; }
public string username { get; set; }
public DateTime createtime { get; set; }
}
public class mto_topic_nav
{
public Guid id { get; set; }
public Guid user_nav_pkid { get; set; }
[Navigate("user_nav_pkid")]
public virtual mto_user_nav user { get; set; }
public string title { get; set; }
public DateTime createtime { get; set; }
}
#endregion
}
}

View File

@ -0,0 +1,138 @@
using FreeSql.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Numerics;
using Xunit;
namespace FreeSql.Tests.DataAnnotations
{
public class OneToManyTest
{
#region
[Fact]
public void Select()
{
var users = new mto_user[10];
var topics = new mto_topic[30];
for (var a = 0; a < users.Length; a++)
{
var uid = Guid.NewGuid();
users[a] = new mto_user
{
id = uid,
username = Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3] = new mto_topic
{
id = Guid.NewGuid(),
mto_userid = uid,
title = "测试标标题" + (a * 3) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3 + 1] = new mto_topic
{
id = Guid.NewGuid(),
mto_userid = uid,
title = "测试标标题" + (a * 3 + 1) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3 + 2] = new mto_topic
{
id = Guid.NewGuid(),
mto_userid = uid,
title = "测试标标题" + (a * 3 + 2) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
}
g.sqlite.Insert(users).ExecuteAffrows();
g.sqlite.Insert(topics).ExecuteAffrows();
var select1 = g.sqlite.Select<mto_user>().Limit(10).OrderByDescending(a => a.createtime).ToList(true);
var select2 = g.sqlite.Select<mto_user>().IncludeMany(a => a.mto_topics).Limit(10).OrderByDescending(a => a.createtime).ToList(true);
}
public class mto_user
{
public Guid id { get; set; }
public string username { get; set; }
public DateTime createtime { get; set; }
public virtual List<mto_topic> mto_topics { get; set; }
}
public class mto_topic
{
public Guid id { get; set; }
public Guid mto_userid { get; set; }
public string title { get; set; }
public DateTime createtime { get; set; }
}
#endregion
#region
[Fact]
public void Navigate()
{
var users = new otm_user_nav[10];
var topics = new otm_topic_nav[30];
for (var a = 0; a < users.Length; a++)
{
var uid = Guid.NewGuid();
users[a] = new otm_user_nav
{
id = uid,
username = Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3] = new otm_topic_nav
{
id = Guid.NewGuid(),
user_nav_pkid = uid,
title = "测试标标题" + (a * 3) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3 + 1] = new otm_topic_nav
{
id = Guid.NewGuid(),
user_nav_pkid = uid,
title = "测试标标题" + (a * 3 + 1) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
topics[a * 3 + 2] = new otm_topic_nav
{
id = Guid.NewGuid(),
user_nav_pkid = uid,
title = "测试标标题" + (a * 3 + 2) + Guid.NewGuid().ToString("N"),
createtime = DateTime.Now
};
}
g.sqlite.Insert(users).ExecuteAffrows();
g.sqlite.Insert(topics).ExecuteAffrows();
var select1 = g.sqlite.Select<otm_user_nav>().Limit(10).OrderByDescending(a => a.createtime).ToList(true);
var select2 = g.sqlite.Select<otm_user_nav>().IncludeMany(a => a.topics).Limit(10).OrderByDescending(a => a.createtime).ToList(true);
}
public class otm_user_nav
{
public Guid id { get; set; }
public string username { get; set; }
public DateTime createtime { get; set; }
[Navigate("user_nav_pkid")]
public virtual List<otm_topic_nav> topics { get; set; }
}
public class otm_topic_nav
{
public Guid id { get; set; }
public Guid user_nav_pkid { get; set; }
public string title { get; set; }
public DateTime createtime { get; set; }
}
#endregion
}
}

View File

@ -0,0 +1,60 @@
using FreeSql.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Xunit;
namespace FreeSql.Tests.DataAnnotations
{
public class OneToOneTest
{
[Fact]
public void Select()
{
var users = new oto_user[10];
for (var a = 0; a < users.Length; a++)
{
var uid = Guid.NewGuid();
users[a] = new oto_user
{
id = uid,
username = Guid.NewGuid().ToString("N"),
createtime = DateTime.Now,
ext = new oto_user_field
{
userid = uid,
age = a,
createtime = DateTime.Now
}
};
}
g.sqlite.Insert(users).ExecuteAffrows();
g.sqlite.Insert(users.Select(a => a.ext).ToArray()).ExecuteAffrows();
var select1 = g.sqlite.Select<oto_user>().Include(a => a.ext).Limit(10).OrderByDescending(a => a.createtime).ToList(true);
var select2 = g.sqlite.Select<oto_user_field>().Limit(10).OrderByDescending(a => a.createtime).ToList(true);
var select3 = g.sqlite.Select<oto_user_field>().Include(a => a.user).Limit(10).OrderByDescending(a => a.createtime).ToList(true);
}
public class oto_user
{
public Guid id { get; set; }
public string username { get; set; }
public DateTime createtime { get; set; }
public oto_user_field ext { get; set; }
}
public class oto_user_field
{
[Column(IsPrimary = true)]
public Guid userid { get; set; }
public virtual oto_user user { get; set; }
public int age { get; set; }
public DateTime createtime { get; set; }
}
}
}

View File

@ -7,13 +7,20 @@ namespace FreeSql.DataAnnotations
{
/// <summary>
/// 导航属性,手工绑定
/// 手工绑定 OneToMany、ManyToOne 导航关系
/// </summary>
public string Bind { get; set; }
/// <summary>
/// 手工绑定 ManyToMany 导航关系
/// </summary>
public Type ManyToMany { get; set; }
public NavigateAttribute(string bind)
{
this.Bind = bind;
}
public NavigateAttribute()
{
}
}
}

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.7.8</Version>
<Version>0.7.9</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>

View File

@ -115,7 +115,12 @@
</member>
<member name="P:FreeSql.DataAnnotations.NavigateAttribute.Bind">
<summary>
导航属性,手工绑定
手工绑定 OneToMany、ManyToOne 导航关系
</summary>
</member>
<member name="P:FreeSql.DataAnnotations.NavigateAttribute.ManyToMany">
<summary>
手工绑定 ManyToMany 导航关系
</summary>
</member>
<member name="P:FreeSql.DataAnnotations.TableAttribute.Name">

View File

@ -902,9 +902,7 @@ namespace FreeSql.Internal.CommonProvider
{
string key = null;
if (tbref.Columns.Count == 1)
{
key = _orm.GetEntityValueWithPropertyName(tbref.RefMiddleEntityType, midList[a], tbref.MiddleColumns[0].CsName).ToString();
}
else
{
var sb = new StringBuilder();

View File

@ -208,25 +208,20 @@ namespace FreeSql.Internal
{
if (trytb.Columns.TryGetValue(dbident.Name, out var trycol) && trycol.Attribute.MapType == dbident.CsType ||
trytb.ColumnsByCs.TryGetValue(dbident.Name, out trycol) && trycol.Attribute.MapType == dbident.CsType)
{
trycol.Attribute.IsIdentity = true;
}
}
foreach (var dbpk in dbtb.Primarys)
{
if (trytb.Columns.TryGetValue(dbpk.Name, out var trycol) && trycol.Attribute.MapType == dbpk.CsType ||
trytb.ColumnsByCs.TryGetValue(dbpk.Name, out trycol) && trycol.Attribute.MapType == dbpk.CsType)
{
trycol.Attribute.IsPrimary = true;
}
}
foreach (var dbuk in dbtb.UniquesDict)
{
foreach (var dbcol in dbuk.Value)
{
if (trytb.Columns.TryGetValue(dbcol.Name, out var trycol) && trycol.Attribute.MapType == dbcol.CsType ||
trytb.ColumnsByCs.TryGetValue(dbcol.Name, out trycol) && trycol.Attribute.MapType == dbcol.CsType)
{
if (trycol.Attribute._Uniques?.Contains(dbuk.Key) != true)
trycol.Attribute.Unique += $"," + dbuk.Key;
}
@ -234,7 +229,6 @@ namespace FreeSql.Internal
}
}
}
}
catch { }
trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray();
}
@ -272,7 +266,8 @@ namespace FreeSql.Internal
$"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace}.{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace}.{a.Name}"))}>" :
(pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace}.{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace}.{pnv.PropertyType.Name}");
var pnvBind = pnv.GetCustomAttribute<NavigateAttribute>()?.Bind.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray();
var pnvAttr = pnv.GetCustomAttribute<NavigateAttribute>();
var pnvBind = pnvAttr?.Bind?.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray();
var nvref = new TableRef();
nvref.Property = pnv;
@ -294,11 +289,47 @@ namespace FreeSql.Internal
var tbrefTypeName = tbref.Type.IsNested ? $"{tbref.Type.DeclaringType.Namespace}.{tbref.Type.DeclaringType.Name}.{tbref.Type.Name}" : $"{tbref.Type.Namespace}.{tbref.Type.Name}";
Type midType = null;
var isManyToMany = propElementType != trytb.Type &&
pnv.Name.EndsWith($"{tbref.CsName}s") &&
var isManyToMany = false;
Action valiManyToMany = () =>
{
if (midType != null)
{
var midTypeProps = midType.GetProperties();
var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count();
var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count();
if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null;
}
};
if (pnvAttr?.ManyToMany != null)
{
isManyToMany = propElementType != trytb.Type &&
tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) &&
z.Value.GetCustomAttribute<NavigateAttribute>()?.ManyToMany == pnvAttr.ManyToMany &&
typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any();
if (isManyToMany == false)
{
nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,实体类型 {tbrefTypeName} 必须存在对应的 [Navigate(ManyToMany = x)] 集合属性");
trytb.AddOrUpdateTableRef(pnv.Name, nvref);
//if (isLazy) throw nvref.Exception;
continue;
}
if (isManyToMany)
{
midType = pnvAttr.ManyToMany;
valiManyToMany();
}
}
else
{
isManyToMany = propElementType != trytb.Type &&
pnv.Name.EndsWith($"{tbref.CsName}s", StringComparison.CurrentCultureIgnoreCase) &&
tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) &&
z.Key.EndsWith($"{trytb.CsName}s", StringComparison.CurrentCultureIgnoreCase) &&
typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any();
}
if (isManyToMany)
{
if (tbref.Primarys.Any() == false)
@ -308,59 +339,41 @@ namespace FreeSql.Internal
//if (isLazy) throw nvref.Exception;
continue;
}
if (pnvAttr?.ManyToMany == null)
{
//中间表怎么查询,比如 Song、Tag、SongTag
var midFlagStr = pnv.Name.Remove(pnv.Name.Length - tbref.CsName.Length - 1);
var midFlagStr = string.Empty;
if (pnv.Name.Length >= tbref.CsName.Length - 1)
midFlagStr = pnv.Name.Remove(pnv.Name.Length - tbref.CsName.Length - 1);
#region trytb
if (midType == null)
{
midType = trytb.Type.IsNested ?
trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag
trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true);
if (midType != null)
{
var midTypeProps = midType.GetProperties();
var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count();
var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count();
if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null;
valiManyToMany();
}
if (midType == null)
{
midType = trytb.Type.IsNested ?
trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag
trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true);
if (midType != null)
{
var midTypeProps = midType.GetProperties();
var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count();
var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count();
if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null;
}
valiManyToMany();
}
if (midType == null)
{
midType = trytb.Type.IsNested ?
trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong
trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true);
if (midType != null)
{
var midTypeProps = midType.GetProperties();
var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count();
var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count();
if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null;
}
valiManyToMany();
}
if (midType == null)
{
midType = trytb.Type.IsNested ?
trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{trytb.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song
trytb.Type.Assembly.GetType($"{trytb.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true);
if (midType != null)
{
var midTypeProps = midType.GetProperties();
var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count();
var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count();
if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null;
}
valiManyToMany();
}
#endregion
@ -370,54 +383,31 @@ namespace FreeSql.Internal
midType = tbref.Type.IsNested ?
tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true) : //SongTag
tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}{tbref.CsName}{midFlagStr}", false, true);
if (midType != null)
{
var midTypeProps = midType.GetProperties();
var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count();
var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count();
if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null;
}
valiManyToMany();
}
if (midType == null)
{
midType = tbref.Type.IsNested ?
tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Song_Tag
tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{trytb.CsName}_{tbref.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true);
if (midType != null)
{
var midTypeProps = midType.GetProperties();
var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count();
var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count();
if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null;
}
valiManyToMany();
}
if (midType == null)
{
midType = tbref.Type.IsNested ?
tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true) : //TagSong
tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}{trytb.CsName}{midFlagStr}", false, true);
if (midType != null)
{
var midTypeProps = midType.GetProperties();
var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count();
var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count();
if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null;
}
valiManyToMany();
}
if (midType == null)
{
midType = tbref.Type.IsNested ?
tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.Type.DeclaringType.Name}+{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true) : //Tag_Song
tbref.Type.Assembly.GetType($"{tbref.Type.Namespace}.{tbref.CsName}_{trytb.CsName}{(string.IsNullOrEmpty(midFlagStr) ? "" : "_")}{midFlagStr}", false, true);
if (midType != null)
{
var midTypeProps = midType.GetProperties();
var midTypePropsTrytb = midTypeProps.Where(a => a.PropertyType == trytb.Type).Count();
var midTypePropsTbref = midTypeProps.Where(a => a.PropertyType == tbref.Type).Count();
if (midTypePropsTrytb != 1 || midTypePropsTbref != 1) midType = null;
}
valiManyToMany();
}
#endregion
}
isManyToMany = midType != null;
}
@ -427,6 +417,90 @@ namespace FreeSql.Internal
var midTypePropsTrytb = tbmid.Properties.Where(a => a.Value.PropertyType == trytb.Type).FirstOrDefault().Value;
//g.mysql.Select<Tag>().Where(a => g.mysql.Select<Song_tag>().Where(b => b.Tag_id == a.Id && b.Song_id == 1).Any());
var lmbdWhere = isLazy ? new StringBuilder() : null;
if (pnvAttr?.ManyToMany != null)
{
#region Navigate[ManyToMany = x]
TableRef trytbTf = null;
try
{
trytbTf = tbmid.GetTableRef(midTypePropsTrytb.Name, true);
}
catch (Exception ex)
{
nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTrytb.Name} 错误:{ex.Message}");
trytb.AddOrUpdateTableRef(pnv.Name, nvref);
//if (isLazy) throw nvref.Exception;
}
if (nvref.Exception == null)
{
if (trytbTf.RefType != TableRefType.ManyToOne && trytbTf.RefType != TableRefType.OneToOne)
{
nvref.Exception = new Exception($"【ManyToMany】导航属性 {trytbTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTrytb.Name} 导航属性不是【ManyToOne】或【OneToOne】");
trytb.AddOrUpdateTableRef(pnv.Name, nvref);
//if (isLazy) throw nvref.Exception;
}
else
{
nvref.Columns.AddRange(trytbTf.RefColumns);
nvref.MiddleColumns.AddRange(trytbTf.Columns);
if (tbmid.Primarys.Any() == false)
trytbTf.Columns.Select(c => tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true);
if (isLazy)
{
for (var a = 0; a < trytbTf.RefColumns.Count; a++)
{
if (a > 0) lmbdWhere.Append(" && ");
lmbdWhere.Append("b.").Append(trytbTf.Columns[a].CsName).Append(" == this.").Append(trytbTf.RefColumns[a].CsName);
}
}
}
}
if (nvref.Exception == null)
{
var midTypePropsTbref = tbmid.Properties.Where(a => a.Value.PropertyType == tbref.Type).FirstOrDefault().Value;
TableRef tbrefTf = null;
try
{
tbrefTf = tbmid.GetTableRef(midTypePropsTbref.Name, true);
}
catch (Exception ex)
{
nvref.Exception = new Exception($"【ManyToMany】导航属性 {tbrefTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTbref.Name} 错误:{ex.Message}");
trytb.AddOrUpdateTableRef(pnv.Name, nvref);
//if (isLazy) throw nvref.Exception;
}
if (nvref.Exception == null)
{
if (tbrefTf.RefType != TableRefType.ManyToOne && tbrefTf.RefType != TableRefType.OneToOne)
{
nvref.Exception = new Exception($"【ManyToMany】导航属性 {tbrefTypeName}.{pnv.Name} 解析错误,中间类 {tbmid.CsName}.{midTypePropsTbref.Name} 导航属性不是【ManyToOne】或【OneToOne】");
trytb.AddOrUpdateTableRef(pnv.Name, nvref);
//if (isLazy) throw nvref.Exception;
}
else
{
nvref.RefColumns.AddRange(tbrefTf.RefColumns);
nvref.MiddleColumns.AddRange(tbrefTf.Columns);
if (tbmid.Primarys.Any() == false)
tbrefTf.Columns.Select(c => tbmid.ColumnsByCs[c.CsName].Attribute.IsPrimary = true);
if (isLazy)
{
for (var a = 0; a < tbrefTf.RefColumns.Count; a++)
lmbdWhere.Append(" && b.").Append(tbrefTf.Columns[a].CsName).Append(" == a.").Append(tbrefTf.RefColumns[a].CsName);
}
}
}
}
#endregion
}
else
{
#region
for (var a = 0; a < trytb.Primarys.Length; a++)
{
var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_');
@ -500,6 +574,8 @@ namespace FreeSql.Internal
if (isLazy) lmbdWhere.Append(" && b.").Append(trycol.CsName).Append(" == a.").Append(tbref.Primarys[a].CsName);
}
}
#endregion
}
if (nvref.Columns.Count > 0 && nvref.RefColumns.Count > 0)
{
nvref.RefMiddleEntityType = tbmid.Type;
@ -586,7 +662,7 @@ namespace FreeSql.Internal
var findtrytbPkCsName = trytb.Primarys[a].CsName.TrimStart('_');
if (findtrytbPkCsName.StartsWith(trytb.Type.Name, StringComparison.CurrentCultureIgnoreCase)) findtrytbPkCsName = findtrytbPkCsName.Substring(trytb.Type.Name.Length).TrimStart('_');
var findtrytb = pnv.Name;
if (findtrytb.EndsWith(tbref.CsName + "s")) findtrytb = findtrytb.Substring(0, findtrytb.Length - tbref.CsName.Length - 1);
if (findtrytb.EndsWith($"{tbref.CsName}s", StringComparison.CurrentCultureIgnoreCase)) findtrytb = findtrytb.Substring(0, findtrytb.Length - tbref.CsName.Length - 1);
findtrytb += trytb.CsName;
var trycol = bindColumns.Any() ? bindColumns[a] : null;

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net452</TargetFrameworks>
<Version>0.7.8</Version>
<Version>0.7.9</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 MySql 5.6</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.7.8</Version>
<Version>0.7.9</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 MySql 5.6</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.7.8</Version>
<Version>0.7.9</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 Oracle 11</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.7.8</Version>
<Version>0.7.9</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 PostgreSQL 9.5</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net451</TargetFrameworks>
<Version>0.7.8</Version>
<Version>0.7.9</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 SqlServer 2005+并根据版本适配分页方法row_number 或 offset fetch next</Description>

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
<Version>0.7.8</Version>
<Version>0.7.9</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>YeXiangQin</Authors>
<Description>FreeSql 数据库实现,基于 Sqlite 3.0</Description>