mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
- 增加 IDelete.ToSqlCascade 递归删除方法;
This commit is contained in:
parent
fc3dc35617
commit
88d7985d92
@ -538,14 +538,5 @@
|
|||||||
<param name="that"></param>
|
<param name="that"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
|
|
||||||
<summary>
|
|
||||||
批量注入 Repository,可以参考代码自行调整
|
|
||||||
</summary>
|
|
||||||
<param name="services"></param>
|
|
||||||
<param name="globalDataFilter"></param>
|
|
||||||
<param name="assemblies"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
</members>
|
</members>
|
||||||
</doc>
|
</doc>
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
|
using FreeSql;
|
||||||
using FreeSql.DataAnnotations;
|
using FreeSql.DataAnnotations;
|
||||||
|
using FreeSql.Internal.CommonProvider;
|
||||||
|
using FreeSql.Internal.Model;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace FreeSql.Tests.Sqlite
|
namespace FreeSql.Tests.Sqlite
|
||||||
@ -104,3 +109,120 @@ namespace FreeSql.Tests.Sqlite
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class DeleteExtensions
|
||||||
|
{
|
||||||
|
public static string ToSqlCascade<T>(this IDelete<T> that)
|
||||||
|
{
|
||||||
|
var delete = that as DeleteProvider;
|
||||||
|
if (delete == null) return null;
|
||||||
|
if (delete._whereTimes <= 0 || delete._where.Length == 0) return null;
|
||||||
|
if (LocalGetNavigates(delete._table).Any() == false) return that.ToSql();
|
||||||
|
|
||||||
|
var fsql = delete._orm;
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
Dictionary<string, bool> eachdic = new Dictionary<string, bool>();
|
||||||
|
|
||||||
|
var rootSel = fsql.Select<object>().AsType(delete._table.Type).Where(delete._where.ToString());
|
||||||
|
var rootItems = rootSel.ToList();
|
||||||
|
LocalEach(delete._table.Type, rootItems, true);
|
||||||
|
return sb.ToString();
|
||||||
|
|
||||||
|
List<NativeTuple<TableRef, PropertyInfo>> LocalGetNavigates(TableInfo tb)
|
||||||
|
{
|
||||||
|
return tb.Properties.Where(a => tb.ColumnsByCs.ContainsKey(a.Key) == false)
|
||||||
|
.Select(a => new NativeTuple<TableRef, PropertyInfo>(tb.GetTableRef(a.Key, false), a.Value))
|
||||||
|
.Where(a => a.Item1 != null && a.Item1.RefType != TableRefType.ManyToOne)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
void LocalEach(Type itemType, List<object> items, bool isOneToOne)
|
||||||
|
{
|
||||||
|
items = items?.Where(item =>
|
||||||
|
{
|
||||||
|
var itemKeystr = FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityKeyString(fsql, itemType, item, false);
|
||||||
|
var eachdicKey = $"{itemType.FullName},{itemKeystr}";
|
||||||
|
if (eachdic.ContainsKey(eachdicKey)) return false;
|
||||||
|
eachdic.Add(eachdicKey, true);
|
||||||
|
return true;
|
||||||
|
}).ToList();
|
||||||
|
if (items?.Any() != true) return;
|
||||||
|
|
||||||
|
var tb = fsql.CodeFirst.GetTableByEntity(itemType);
|
||||||
|
var navs = LocalGetNavigates(tb);
|
||||||
|
|
||||||
|
var otos = navs.Where(a => a.Item1.RefType == TableRefType.OneToOne).ToList();
|
||||||
|
if (otos.Any())
|
||||||
|
{
|
||||||
|
foreach (var oto in otos)
|
||||||
|
{
|
||||||
|
var childsSel = fsql.Select<object>().AsType(oto.Item1.RefEntityType) as Select1Provider<object>;
|
||||||
|
var refitems = items.Select(item =>
|
||||||
|
{
|
||||||
|
var refitem = oto.Item1.RefEntityType.CreateInstanceGetDefaultValue();
|
||||||
|
for (var a = 0; a < oto.Item1.Columns.Count; a++)
|
||||||
|
{
|
||||||
|
var colval = FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetPropertyValue(tb, item, oto.Item1.Columns[a].CsName);
|
||||||
|
FreeSql.Extensions.EntityUtil.EntityUtilExtensions.SetPropertyValue(childsSel._tables[0].Table, refitem, oto.Item1.RefColumns[a].CsName, colval);
|
||||||
|
}
|
||||||
|
return refitem;
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
childsSel.Where(childsSel._commonUtils.WhereItems(oto.Item1.RefColumns.ToArray(), "a.", refitems));
|
||||||
|
var childs = childsSel.ToList();
|
||||||
|
LocalEach(oto.Item1.RefEntityType, childs, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var otms = navs.Where(a => a.Item1.RefType == TableRefType.OneToMany).ToList();
|
||||||
|
if (otms.Any())
|
||||||
|
{
|
||||||
|
foreach (var otm in otms)
|
||||||
|
{
|
||||||
|
var childsSel = fsql.Select<object>().AsType(otm.Item1.RefEntityType) as Select1Provider<object>;
|
||||||
|
var refitems = items.Select(item =>
|
||||||
|
{
|
||||||
|
var refitem = otm.Item1.RefEntityType.CreateInstanceGetDefaultValue();
|
||||||
|
for (var a = 0; a < otm.Item1.Columns.Count; a++)
|
||||||
|
{
|
||||||
|
var colval = FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetPropertyValue(tb, item, otm.Item1.Columns[a].CsName);
|
||||||
|
FreeSql.Extensions.EntityUtil.EntityUtilExtensions.SetPropertyValue(childsSel._tables[0].Table, refitem, otm.Item1.RefColumns[a].CsName, colval);
|
||||||
|
}
|
||||||
|
return refitem;
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
childsSel.Where(childsSel._commonUtils.WhereItems(otm.Item1.RefColumns.ToArray(), "a.", refitems));
|
||||||
|
var childs = childsSel.ToList();
|
||||||
|
LocalEach(otm.Item1.RefEntityType, childs, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var mtms = navs.Where(a => a.Item1.RefType == TableRefType.ManyToMany).ToList();
|
||||||
|
if (mtms.Any())
|
||||||
|
{
|
||||||
|
foreach (var mtm in mtms)
|
||||||
|
{
|
||||||
|
var childsSel = fsql.Select<object>().AsType(mtm.Item1.RefMiddleEntityType) as Select1Provider<object>;
|
||||||
|
var miditems = items.Select(item =>
|
||||||
|
{
|
||||||
|
var refitem = mtm.Item1.RefMiddleEntityType.CreateInstanceGetDefaultValue();
|
||||||
|
for (var a = 0; a < mtm.Item1.Columns.Count; a++)
|
||||||
|
{
|
||||||
|
var colval = FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetPropertyValue(tb, item, mtm.Item1.Columns[a].CsName);
|
||||||
|
FreeSql.Extensions.EntityUtil.EntityUtilExtensions.SetPropertyValue(childsSel._tables[0].Table, refitem, mtm.Item1.MiddleColumns[a].CsName, colval);
|
||||||
|
}
|
||||||
|
return refitem;
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
childsSel.Where(childsSel._commonUtils.WhereItems(mtm.Item1.MiddleColumns.Take(mtm.Item1.Columns.Count).ToArray(), "a.", miditems));
|
||||||
|
var childs = childsSel.ToList();
|
||||||
|
LocalEach(mtm.Item1.RefEntityType, childs, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var delSql = fsql.Delete<object>().AsType(itemType).WhereDynamic(items).ToSql();
|
||||||
|
if (string.IsNullOrWhiteSpace(delSql)) throw new Exception($"ToSqlCascade 失败");
|
||||||
|
if (sb.Length > 0) sb.Append("\r\n\r\n;\r\n\r\n");
|
||||||
|
sb.Append(delSql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -373,6 +373,8 @@ WHERE (((a.""Name"") in (SELECT s.""Title"" as1
|
|||||||
var ddd = g.sqlite.Select<District>().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList();
|
var ddd = g.sqlite.Select<District>().LeftJoin(d => d.ParentCode == d.Parent.Code).ToTreeList();
|
||||||
Assert.Single(ddd);
|
Assert.Single(ddd);
|
||||||
Assert.Equal(2, ddd[0].Childs.Count);
|
Assert.Equal(2, ddd[0].Childs.Count);
|
||||||
|
|
||||||
|
var sql = g.sqlite.Delete<District>().Where(a => a.Code == "001").ToSqlCascade();
|
||||||
}
|
}
|
||||||
public class District
|
public class District
|
||||||
{
|
{
|
||||||
@ -1281,6 +1283,7 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title""
|
|||||||
};
|
};
|
||||||
Assert.Equal(5, g.sqlite.Insert(model4s).ExecuteAffrows());
|
Assert.Equal(5, g.sqlite.Insert(model4s).ExecuteAffrows());
|
||||||
|
|
||||||
|
|
||||||
var by0 = g.sqlite.Select<TestInclude_OneToManyModel2>()
|
var by0 = g.sqlite.Select<TestInclude_OneToManyModel2>()
|
||||||
.Where(a => a.model2id <= model1.id)
|
.Where(a => a.model2id <= model1.id)
|
||||||
.ToList();
|
.ToList();
|
||||||
@ -1305,6 +1308,8 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title""
|
|||||||
.Where(a => a.id <= model1.id)
|
.Where(a => a.id <= model1.id)
|
||||||
.ToList();
|
.ToList();
|
||||||
by1.IncludeByPropertyName(g.sqlite, "model2.childs", "model2111Idaaa=model2id");
|
by1.IncludeByPropertyName(g.sqlite, "model2.childs", "model2111Idaaa=model2id");
|
||||||
|
|
||||||
|
by1.IncludeByPropertyNameAsync(g.sqlite, "model2.childs", "model2111Idaaa=model2id");
|
||||||
var t1 = g.sqlite.Select<TestInclude_OneToManyModel1>()
|
var t1 = g.sqlite.Select<TestInclude_OneToManyModel1>()
|
||||||
.IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id))
|
.IncludeMany(a => a.model2.childs.Where(m3 => m3.model2111Idaaa == a.model2.model2id))
|
||||||
.Where(a => a.id <= model1.id)
|
.Where(a => a.id <= model1.id)
|
||||||
@ -2233,6 +2238,8 @@ WHERE (((cast(a.""Id"" as character)) in (SELECT b.""Title""
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var sql = g.sqlite.Delete<VM_District_Child>().Where(a => a.Code == "100000").ToSqlCascade();
|
||||||
|
|
||||||
var t1 = fsql.Select<VM_District_Parent>()
|
var t1 = fsql.Select<VM_District_Parent>()
|
||||||
.InnerJoin(a => a.ParentCode == a.Parent.Code)
|
.InnerJoin(a => a.ParentCode == a.Parent.Code)
|
||||||
.Where(a => a.Code == "110101")
|
.Where(a => a.Code == "110101")
|
||||||
|
@ -201,7 +201,8 @@ public static partial class FreeSqlGlobalExtensions
|
|||||||
var value = dr.GetString(index);
|
var value = dr.GetString(index);
|
||||||
var t = typeof(T);
|
var t = typeof(T);
|
||||||
var fs = _dicGetFields.GetOrAdd(t, t2 => t2.GetFields());
|
var fs = _dicGetFields.GetOrAdd(t, t2 => t2.GetFields());
|
||||||
foreach (var f in fs) {
|
foreach (var f in fs)
|
||||||
|
{
|
||||||
var attr = f.GetCustomAttributes(typeof(DescriptionAttribute), false)?.FirstOrDefault() as DescriptionAttribute;
|
var attr = f.GetCustomAttributes(typeof(DescriptionAttribute), false)?.FirstOrDefault() as DescriptionAttribute;
|
||||||
if (attr?.Description == value || f.Name == value) return Enum.Parse(t, f.Name, true);
|
if (attr?.Description == value || f.Name == value) return Enum.Parse(t, f.Name, true);
|
||||||
}
|
}
|
||||||
@ -343,6 +344,29 @@ public static partial class FreeSqlGlobalExtensions
|
|||||||
/// <exception cref="ArgumentException"></exception>
|
/// <exception cref="ArgumentException"></exception>
|
||||||
public static List<T1> IncludeByPropertyName<T1>(this List<T1> list, IFreeSql orm, string property, string where = null, int take = 0, string select = null) where T1 : class
|
public static List<T1> IncludeByPropertyName<T1>(this List<T1> list, IFreeSql orm, string property, string where = null, int take = 0, string select = null) where T1 : class
|
||||||
{
|
{
|
||||||
|
#if net40
|
||||||
|
return IncludeByPropertyNameSyncOrAsync<T1>(false, list, orm, property, where, take, select);
|
||||||
|
#else
|
||||||
|
var task = IncludeByPropertyNameSyncOrAsync<T1>(false, list, orm, property, where, take, select);
|
||||||
|
if (task.Exception != null) throw task.Exception.InnerException ?? task.Exception;
|
||||||
|
return task.Result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if net40
|
||||||
|
#else
|
||||||
|
public static Task<List<T1>> IncludeByPropertyNameAsync<T1>(this List<T1> list, IFreeSql orm, string property, string where = null, int take = 0, string select = null) where T1 : class
|
||||||
|
{
|
||||||
|
return IncludeByPropertyNameSyncOrAsync<T1>(true, list, orm, property, where, take, select);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
static
|
||||||
|
#if net40
|
||||||
|
List<T1>
|
||||||
|
#else
|
||||||
|
async Task<List<T1>>
|
||||||
|
#endif
|
||||||
|
IncludeByPropertyNameSyncOrAsync<T1>(bool isAsync, List<T1> list, IFreeSql orm, string property, string where = null, int take = 0, string select = null) where T1 : class
|
||||||
|
{
|
||||||
if (orm.CodeFirst.IsAutoSyncStructure)
|
if (orm.CodeFirst.IsAutoSyncStructure)
|
||||||
{
|
{
|
||||||
var tb = orm.CodeFirst.GetTableByEntity(typeof(T1));
|
var tb = orm.CodeFirst.GetTableByEntity(typeof(T1));
|
||||||
@ -360,7 +384,13 @@ public static partial class FreeSqlGlobalExtensions
|
|||||||
{
|
{
|
||||||
if (props.Length > 1)
|
if (props.Length > 1)
|
||||||
IncludeByPropertyName(list, orm, string.Join(".", props.Take(props.Length - 1)));
|
IncludeByPropertyName(list, orm, string.Join(".", props.Take(props.Length - 1)));
|
||||||
IncludeManyByPropertyNameCommonGetSelect<T1>(orm, property, where, take, select).SetList(list);
|
var imsel = IncludeManyByPropertyNameCommonGetSelect<T1>(orm, property, where, take, select);
|
||||||
|
#if net40
|
||||||
|
imsel.SetList(list);
|
||||||
|
#else
|
||||||
|
if (isAsync) await imsel.SetListAsync(list);
|
||||||
|
else imsel.SetList(list);
|
||||||
|
#endif
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
var tbtr = t1tb.GetTableRef(props[0], true);
|
var tbtr = t1tb.GetTableRef(props[0], true);
|
||||||
@ -388,7 +418,13 @@ public static partial class FreeSqlGlobalExtensions
|
|||||||
};
|
};
|
||||||
}).GroupBy(a => a.key).ToDictionary(a => a.Key, a => a);
|
}).GroupBy(a => a.key).ToDictionary(a => a.Key, a => a);
|
||||||
refsel.WhereDynamic(listdic.Values.Select(a => a.First().refitem).ToList());
|
refsel.WhereDynamic(listdic.Values.Select(a => a.First().refitem).ToList());
|
||||||
|
|
||||||
|
#if net40
|
||||||
var reflist = refsel.ToList();
|
var reflist = refsel.ToList();
|
||||||
|
#else
|
||||||
|
var reflist = isAsync ? await refsel.ToListAsync() : refsel.ToList();
|
||||||
|
#endif
|
||||||
|
|
||||||
reflist.ForEach(refitem =>
|
reflist.ForEach(refitem =>
|
||||||
{
|
{
|
||||||
var key = FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityKeyString(orm, reftb.Type, refitem, false);
|
var key = FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityKeyString(orm, reftb.Type, refitem, false);
|
||||||
@ -473,7 +509,7 @@ public static partial class FreeSqlGlobalExtensions
|
|||||||
incMethod.MakeGenericMethod(reftb.Type).Invoke(sel, new object[] { navigateSelector, null });
|
incMethod.MakeGenericMethod(reftb.Type).Invoke(sel, new object[] { navigateSelector, null });
|
||||||
return sel;
|
return sel;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ToTreeList() 父子分类
|
#region ToTreeList() 父子分类
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -1162,7 +1198,7 @@ SELECT ");
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user