Skip to content

Commit b701ad8

Browse files
committed
- 增加 IncludeByPropertyName 按属性名进行 Include/IncludeMany 操作;#278
1 parent 856ecf2 commit b701ad8

File tree

5 files changed

+71
-2
lines changed

5 files changed

+71
-2
lines changed

FreeSql.Tests/FreeSql.Tests/UnitTest3.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ public class tcate01
191191
{
192192
[Column(IsIdentity = true)]
193193
public int? Id { get; set; }
194+
195+
public string name { get; set; }
196+
[Navigate(nameof(tshop01.cateId))]
197+
public List<tshop01> tshops { get; set; }
194198
}
195199
public class tshop01
196200
{
@@ -203,7 +207,28 @@ public class tshop01
203207
[Fact]
204208
public void Test03()
205209
{
210+
g.sqlite.Delete<tcate01>().Where("1=1").ExecuteAffrows();
211+
g.sqlite.Delete<tshop01>().Where("1=1").ExecuteAffrows();
212+
var tshoprepo = g.sqlite.GetRepository<tcate01>();
213+
tshoprepo.DbContextOptions.EnableAddOrUpdateNavigateList = true;
214+
tshoprepo.Insert(new tcate01[]
215+
{
216+
new tcate01 { name = "tcate1", tshops = new List<tshop01>{ new tshop01(), new tshop01(), new tshop01() } },
217+
new tcate01 { name = "tcate1", tshops = new List<tshop01>{ new tshop01(), new tshop01(), new tshop01() } }
218+
});
219+
206220
var tshop01sql = g.sqlite.Select<tshop01>().Include(a => a.cate).ToSql();
221+
var tshop02sql = g.sqlite.Select<tshop01>().IncludeByPropertyName("cate").ToSql();
222+
223+
var tshop03sql = g.sqlite.Select<tshop01>().IncludeMany(a => a.cate.tshops).ToSql();
224+
var tshop04sql = g.sqlite.Select<tshop01>().IncludeByPropertyName("cate.tshops").ToSql();
225+
226+
var tshop01lst = g.sqlite.Select<tshop01>().Include(a => a.cate).ToList();
227+
var tshop02lst = g.sqlite.Select<tshop01>().IncludeByPropertyName("cate").ToList();
228+
229+
var tshop03lst = g.sqlite.Select<tshop01>().IncludeMany(a => a.cate.tshops).ToList();
230+
var tshop04lst = g.sqlite.Select<tshop01>().IncludeByPropertyName("cate.tshops").ToList();
231+
207232

208233

209234
var testisnullsql1 = g.sqlite.Select<t102>().Where(a => SqlExt.IsNull(a.isxx, false).Equals( true)).ToSql();

FreeSql/FreeSql.xml

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

FreeSql/Interface/Curd/ISelect/ISelect1.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,13 @@ public interface ISelect<T1> : ISelect0<ISelect<T1>, T1>
333333
/// <returns></returns>
334334
ISelect<T1> IncludeMany<TNavigate>(Expression<Func<T1, IEnumerable<TNavigate>>> navigateSelector, Action<ISelect<TNavigate>> then = null) where TNavigate : class;
335335

336+
/// <summary>
337+
/// 按属性名字符串进行 Include/IncludeMany 操作
338+
/// </summary>
339+
/// <param name="property"></param>
340+
/// <returns></returns>
341+
ISelect<T1> IncludeByPropertyName(string property);
342+
336343
/// <summary>
337344
/// 实现 select .. from ( select ... from t ) a 这样的功能<para></para>
338345
/// 使用 AsTable 方法也可以达到效果<para></para>

FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,13 @@ public static void CopyData(Select0Provider from, Select0Provider to, ReadOnlyCo
121121
to._whereGlobalFilter = new List<GlobalFilter.Item>(from._whereGlobalFilter.ToArray());
122122
}
123123

124-
public Expression ConvertStringPropertyToExpression(string property)
124+
public Expression ConvertStringPropertyToExpression(string property, bool fromFirstTable = false)
125125
{
126126
if (string.IsNullOrEmpty(property)) return null;
127127
var field = property.Split('.').Select(a => a.Trim()).ToArray();
128128
Expression exp = null;
129129

130-
if (field.Length == 1)
130+
if (field.Length == 1 && fromFirstTable == false)
131131
{
132132
foreach (var tb in _tables)
133133
{

FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,36 @@ public bool Any(Expression<Func<T1, bool>> exp)
392392

393393
public int InsertInto<TTargetEntity>(string tableName, Expression<Func<T1, TTargetEntity>> select) where TTargetEntity : class => base.InternalInsertInto<TTargetEntity>(tableName, select);
394394

395+
public ISelect<T1> IncludeByPropertyName(string property)
396+
{
397+
var exp = ConvertStringPropertyToExpression(property, true);
398+
if (exp == null) throw new ArgumentException($"{nameof(property)} 无法解析为表达式树");
399+
var memExp = exp as MemberExpression;
400+
if (memExp == null) throw new ArgumentException($"{nameof(property)} 无法解析为表达式树2");
401+
var parTb = _commonUtils.GetTableByEntity(memExp.Expression.Type);
402+
if (parTb == null) throw new ArgumentException($"{nameof(property)} 无法解析为表达式树3");
403+
var parTbref = parTb.GetTableRef(memExp.Member.Name, true);
404+
if (parTbref == null) throw new ArgumentException($"{nameof(property)} 不是有效的导航属性");
405+
switch (parTbref.RefType)
406+
{
407+
case TableRefType.ManyToMany:
408+
case TableRefType.OneToMany:
409+
var funcType = typeof(Func<,>).MakeGenericType(_tables[0].Table.Type, typeof(IEnumerable<>).MakeGenericType(parTbref.RefEntityType));
410+
var navigateSelector = Expression.Lambda(funcType, exp, _tables[0].Parameter);
411+
var incMethod = this.GetType().GetMethod("IncludeMany");
412+
if (incMethod == null) throw new Exception("运行时错误,反射获取 IncludeMany 方法失败");
413+
incMethod.MakeGenericMethod(parTbref.RefEntityType).Invoke(this, new object[] { navigateSelector, null });
414+
break;
415+
case TableRefType.ManyToOne:
416+
case TableRefType.OneToOne:
417+
_isIncluded = true;
418+
var curTb = _commonUtils.GetTableByEntity(exp.Type);
419+
_commonExpression.ExpressionWhereLambda(_tables, Expression.MakeMemberAccess(exp, curTb.Properties[curTb.ColumnsByCs.First().Value.CsName]), null, null, null);
420+
break;
421+
}
422+
return this;
423+
}
424+
395425
bool _isIncluded = false;
396426
public ISelect<T1> Include<TNavigate>(Expression<Func<T1, TNavigate>> navigateSelector) where TNavigate : class
397427
{

0 commit comments

Comments
 (0)