完善模型通用接口的无限层级一对一和单层级一对多
This commit is contained in:
@@ -43,7 +43,7 @@ public class VengineAppService : BaseAppService, IVengineAppService
|
||||
public async Task<dynamic?> GetAsync(string vmid, [FromQuery] VmGetInput input)
|
||||
{
|
||||
var vm = await _dataAccess.GetVmodelAsync(vmid, true);
|
||||
VmListInput arg = input.Adapt<VmListInput>();
|
||||
VmQueryInput arg = input.Adapt<VmQueryInput>();
|
||||
if (input.id != null)
|
||||
{
|
||||
if (arg.q == null) arg.q = new DObject();
|
||||
@@ -60,7 +60,7 @@ public class VengineAppService : BaseAppService, IVengineAppService
|
||||
public async Task<VmPagedOutput> GetListAsync(string vmid, [FromQuery] VmGetListInput input)
|
||||
{
|
||||
var vm = await _dataAccess.GetVmodelAsync(vmid, true);
|
||||
VmListInput arg = input.Adapt<VmListInput>();
|
||||
VmQueryInput arg = input.Adapt<VmQueryInput>();
|
||||
if (!string.IsNullOrEmpty(input.q))
|
||||
{
|
||||
arg.q = input.q.ToObject<DObject>();
|
||||
@@ -73,7 +73,7 @@ public class VengineAppService : BaseAppService, IVengineAppService
|
||||
/// 获取多条 数据列表
|
||||
/// </summary>
|
||||
[HttpPost("api/[area]/[controller]/{vmid}/list")]
|
||||
public async Task<VmPagedOutput> ListAsync(string vmid, [FromBody] VmListInput input)
|
||||
public async Task<VmPagedOutput> ListAsync(string vmid, [FromBody] VmQueryInput input)
|
||||
{
|
||||
var vm = await _dataAccess.GetVmodelAsync(vmid, true);
|
||||
var ls = await _dataAccess.QueryDataAsync(vm, input);
|
||||
@@ -119,7 +119,7 @@ public class VengineAppService : BaseAppService, IVengineAppService
|
||||
|
||||
private async Task<Vmodel> GetVmodelAsync(string areaCode, string vmCode)
|
||||
{
|
||||
var vm = await _dataAccess.GetVmodelAsync(areaCode, vmCode, true);
|
||||
var vm = await _dataAccess.GetVmodelAsync(areaCode, vmCode, false);
|
||||
return vm;
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ public class VengineAppService : BaseAppService, IVengineAppService
|
||||
public async Task<dynamic?> GetAsync(string areaCode, string vmCode, [FromQuery] VmGetInput input)
|
||||
{
|
||||
var vm = await GetVmodelAsync(areaCode, vmCode);
|
||||
VmListInput arg = input.Adapt<VmListInput>();
|
||||
VmQueryInput arg = input.Adapt<VmQueryInput>();
|
||||
if (input.id != null)
|
||||
{
|
||||
if (arg.q == null) arg.q = new DObject();
|
||||
@@ -147,7 +147,7 @@ public class VengineAppService : BaseAppService, IVengineAppService
|
||||
public async Task<VmPagedOutput> GetListAsync(string areaCode, string vmCode, [FromQuery] VmGetListInput input)
|
||||
{
|
||||
var vm = await GetVmodelAsync(areaCode, vmCode);
|
||||
VmListInput arg = input.Adapt<VmListInput>();
|
||||
VmQueryInput arg = input.Adapt<VmQueryInput>();
|
||||
if (!string.IsNullOrEmpty(input.q))
|
||||
{
|
||||
arg.q = input.q.ToObject<DObject>();
|
||||
@@ -160,7 +160,7 @@ public class VengineAppService : BaseAppService, IVengineAppService
|
||||
/// 获取多条 数据列表
|
||||
/// </summary>
|
||||
[HttpPost("api/{areaCode}/{vmCode}/list")]
|
||||
public async Task<VmPagedOutput> ListAsync(string areaCode, string vmCode, [FromBody] VmListInput input)
|
||||
public async Task<VmPagedOutput> ListAsync(string areaCode, string vmCode, [FromBody] VmQueryInput input)
|
||||
{
|
||||
var vm = await GetVmodelAsync(areaCode, vmCode);
|
||||
var ls = await _dataAccess.QueryDataAsync(vm, input);
|
||||
|
||||
@@ -34,7 +34,7 @@ public class VengineAppService<TEntity> : BaseAppService where TEntity : Entity
|
||||
_db = _dataAccess.GetSqlSugar();
|
||||
}
|
||||
|
||||
protected async Task<Vmodel> GetVmodelAsync()
|
||||
protected virtual async Task<Vmodel> GetVmodelAsync()
|
||||
{
|
||||
var tp = typeof(TEntity);
|
||||
string? area = null, code = null;
|
||||
@@ -53,7 +53,7 @@ public class VengineAppService<TEntity> : BaseAppService where TEntity : Entity
|
||||
{
|
||||
code = tp.Name.ToKebab();
|
||||
}
|
||||
var vm = await _dataAccess.GetVmodelAsync(area, code, true);
|
||||
var vm = await _dataAccess.GetVmodelAsync(area, code, false);
|
||||
|
||||
return vm;
|
||||
}
|
||||
@@ -65,7 +65,7 @@ public class VengineAppService<TEntity> : BaseAppService where TEntity : Entity
|
||||
public virtual async Task<dynamic> GetAsync([FromQuery] VmGetInput input)
|
||||
{
|
||||
var vm = await GetVmodelAsync();
|
||||
VmListInput arg = input.Adapt<VmListInput>();
|
||||
VmQueryInput arg = input.Adapt<VmQueryInput>();
|
||||
if (input.id != null)
|
||||
{
|
||||
if (arg.q == null) arg.q = new DObject();
|
||||
@@ -90,7 +90,7 @@ public class VengineAppService<TEntity> : BaseAppService where TEntity : Entity
|
||||
/// 获取多条 数据列表
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public virtual async Task<VmPagedOutput> ListAsync([FromBody] VmListInput input)
|
||||
public virtual async Task<VmPagedOutput> ListAsync([FromBody] VmQueryInput input)
|
||||
{
|
||||
var vm = await GetVmodelAsync();
|
||||
var ls = await _dataAccess.QueryDataAsync(vm, input);
|
||||
|
||||
@@ -9,6 +9,7 @@ using JNPF.ViewEngine;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
using Tnb.Core;
|
||||
using Tnb.Vengine.DataAccess;
|
||||
using Tnb.Vengine.Domain;
|
||||
|
||||
@@ -65,12 +66,12 @@ public class VmodelAppService : VengineAppService<Vmodel>, IVmodelAppService
|
||||
RefAsync<int> total = 0;
|
||||
var data = await q.OrderBy(input.sort).ToPageListAsync((input.pnum - 1) * input.psize, input.psize, total);
|
||||
ret.total = total;
|
||||
ret.items = data.ConvertAll<dynamic>(a => a);
|
||||
ret.items = data.Adapt<List<DObject>>();
|
||||
return ret;
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
public override Task<VmPagedOutput> ListAsync(VmListInput input)
|
||||
public override Task<VmPagedOutput> ListAsync(VmQueryInput input)
|
||||
{
|
||||
return base.ListAsync(input);
|
||||
}
|
||||
@@ -127,12 +128,17 @@ public class VmodelAppService : VengineAppService<Vmodel>, IVmodelAppService
|
||||
foreach (var tb in lsTable)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(input.removePrefix) && !tb.Name.StartsWith(input.removePrefix)) continue;
|
||||
var n = tb.Name.IndexOf('_');
|
||||
if (string.IsNullOrEmpty(input.removePrefix) && n > 0 && n < 5)
|
||||
{
|
||||
input.removePrefix = tb.Name.Substring(0, n);
|
||||
}
|
||||
var colInfo = sugar.DbMaintenance.GetColumnInfosByTableName(tb.Name);
|
||||
Vmodel model = new() { dbCode = input.dbCode, vmName = tb.Description, tableName = tb.Name };
|
||||
model.areaCode = input.areaCode.ToKebab();
|
||||
model.vmCode = (string.IsNullOrEmpty(input.removePrefix) ? tb.Name.ToKebab() : tb.Name.RemovePreFix(input.removePrefix)).ToKebab();
|
||||
//model.createId = CurrentUser.Id;
|
||||
int n = 1;
|
||||
n = 1;
|
||||
foreach (var p in colInfo)
|
||||
{
|
||||
var prop = p.Adapt<VmDbProp>();
|
||||
|
||||
@@ -9,6 +9,7 @@ using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SqlSugar;
|
||||
using Tnb.Core;
|
||||
using Tnb.Vengine.DataAccess;
|
||||
using Tnb.Vengine.Domain;
|
||||
|
||||
@@ -48,7 +49,7 @@ public class VmodelPageAppService : VengineAppService<VmodelPage>, IVmodelPageAp
|
||||
RefAsync<int> total = 0;
|
||||
var data = await q.OrderBy(input.sort).ToPageListAsync((input.pnum - 1) * input.psize, input.psize, total);
|
||||
ret.total = total;
|
||||
ret.items = data.ConvertAll<dynamic>(a => a);
|
||||
ret.items = data.Adapt<List<DObject>>();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using JNPF;
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Extension;
|
||||
@@ -37,7 +38,7 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
/// <summary>
|
||||
/// 全局缓存
|
||||
/// </summary>
|
||||
private static ConcurrentDictionary<string, ISqlSugarClient> DbCache = new ConcurrentDictionary<string, ISqlSugarClient>();
|
||||
private static readonly ConcurrentDictionary<string, ISqlSugarClient> DbCache = new();
|
||||
|
||||
/// <summary>
|
||||
/// 构造
|
||||
@@ -52,7 +53,7 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var item in DbCache)
|
||||
foreach (KeyValuePair<string, ISqlSugarClient> item in DbCache)
|
||||
{
|
||||
item.Value.Dispose();
|
||||
}
|
||||
@@ -73,9 +74,9 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
return DbCache[dbCode];
|
||||
}
|
||||
|
||||
var dblink = GetVmodelLink(dbCode);
|
||||
VmodelLink dblink = GetVmodelLink(dbCode);
|
||||
ThrowIf.IsNull(dblink, $"没有此数据库{dbCode}连接信息");
|
||||
var sugar = SugarHelper.CreateSugarClient(dblink.dbCode, dblink.dbType, dblink.dbConnection);
|
||||
ISqlSugarClient sugar = SugarHelper.CreateSugarClient(dblink.dbCode, dblink.dbType, dblink.dbConnection);
|
||||
if (sugar.Ado.IsValidConnection())
|
||||
{
|
||||
DbCache[dbCode] = sugar;
|
||||
@@ -93,7 +94,7 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
/// </summary>
|
||||
public VmodelLink GetVmodelLink(string dbCode)
|
||||
{
|
||||
var model = Db.Queryable<VmodelLink>().First(a => a.dbCode == dbCode);
|
||||
VmodelLink model = Db.Queryable<VmodelLink>().First(a => a.dbCode == dbCode);
|
||||
return model;
|
||||
}
|
||||
|
||||
@@ -170,12 +171,12 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
private async Task LoadVmodelNavigateAsync(Vmodel vm)
|
||||
{
|
||||
Dictionary<string, Vmodel> dictVm = new();
|
||||
var vmids = vm.navProps.Select(a => a.vmid).Distinct().ToList();
|
||||
var ls = await Db.Queryable<Vmodel>().Where(a => vmids.Contains(a.id)).ToListAsync();
|
||||
var navs = ls.ToDictionary(a => a.id);
|
||||
foreach (var navProp in vm.navProps)
|
||||
List<string> vmids = vm.navProps.Select(a => a.vmid).Distinct().ToList();
|
||||
List<Vmodel> ls = await Db.Queryable<Vmodel>().Where(a => vmids.Contains(a.id)).ToListAsync();
|
||||
Dictionary<string, Vmodel> navs = ls.ToDictionary(a => a.id);
|
||||
foreach (VmNavProp navProp in vm.navProps)
|
||||
{
|
||||
navProp.naviModel = (Vmodel)navs.GetOrDefault(navProp.vmid);
|
||||
navProp.naviModel = navs.GetOrDefault(navProp.vmid);
|
||||
//if (!dictVm.ContainsKey(navProp.vmid))
|
||||
//{
|
||||
// var navModel = await GetVmodelAsync(navProp.vmid);
|
||||
@@ -184,54 +185,50 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
//navProp.naviModel = dictVm[navProp.vmid];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询数据 默认方法
|
||||
/// </summary>
|
||||
public async Task<VmPagedOutput> QueryDataAsync(Vmodel vm, VmListInput input)
|
||||
public async Task<VmPagedOutput> QueryDataAsync(Vmodel vm, VmQueryInput input)
|
||||
{
|
||||
//var sw = Stopwatch.StartNew();
|
||||
ISqlSugarClient db = GetSqlSugar(vm.dbCode);
|
||||
var query = db.Queryable<object>().AS(vm.tableName, VmSelectProp.MAIN_ALIES);
|
||||
var selProps = vm.GetVmSelectProps(input.o);
|
||||
//处理导航属性联表
|
||||
List<JoinInfoParameter> joins = vm.GetJoinInfos(selProps);
|
||||
//if (joins.Count > 0)
|
||||
query.AddJoinInfo(joins);
|
||||
List<IConditionalModel> wheres = vm.GetConditionalModels(input.q);
|
||||
if (!string.IsNullOrEmpty(input.k))
|
||||
{
|
||||
var lsCondition = new List<KeyValuePair<WhereType, ConditionalModel>>();
|
||||
var wType = WhereType.And;
|
||||
foreach (var prop in vm.dbProps.Where(a => a.fuzzy))
|
||||
{
|
||||
lsCondition.Add(new(wType, new ConditionalModel() { FieldName = prop.field, ConditionalType = ConditionalType.Like, FieldValue = input.k, CSharpTypeName = prop.csType }));
|
||||
wType = WhereType.Or;
|
||||
}
|
||||
wheres.Add(new ConditionalCollections() { ConditionalList = lsCondition });
|
||||
}
|
||||
//处理查询参数
|
||||
//if (wheres.Count > 0)
|
||||
query.Where(wheres);
|
||||
if (!string.IsNullOrEmpty(input.sort))
|
||||
{
|
||||
query.OrderBy(input.sort);
|
||||
}
|
||||
ISugarQueryable<object> query = db.Queryable<object>().AS(vm.tableName, VmQueryParser.MAIN_ALIES);
|
||||
VmQueryParser parser = new(this, vm, input);
|
||||
parser.ParseQueryInput();
|
||||
await parser.LoadNavigateAsync();
|
||||
// 处理导航属性联表
|
||||
List<JoinInfoParameter> joins = parser.GetJoinInfos();
|
||||
_ = query.AddJoinInfo(joins);
|
||||
|
||||
// 处理查询参数条件
|
||||
List<IConditionalModel> wheres = parser.GetConditionalModels();
|
||||
wheres.Add(parser.GetKeywordConditional());
|
||||
_ = query.Where(wheres);
|
||||
|
||||
// 处理排序字段
|
||||
_ = query.OrderBy(parser.GetOrderByModels());
|
||||
|
||||
//处理输出字段
|
||||
List<SelectModel> selects = vm.GetSelectModels(selProps);
|
||||
query.Select(selects);
|
||||
List<SelectModel> selects = parser.GetSelectModels();
|
||||
_ = query.Select(selects);
|
||||
//JNPF.Logging.Log.Debug($"解析查询参数耗时:{sw.ElapsedMilliseconds}ms");
|
||||
//sw.Restart();
|
||||
|
||||
//查询数据
|
||||
VmPagedOutput result = new();
|
||||
List<Dictionary<string, object>> ls = new();
|
||||
int skip = input.pnum > 0 ? (input.pnum - 1) * input.psize : 0;
|
||||
int take = input.psize == 0 ? MAX_PAGE_SIZE : input.psize;
|
||||
if (input.pnum > 0) { result.total = await query.CountAsync(); }
|
||||
ls = await query.Skip(skip).Take(take).ToDictionaryListAsync();
|
||||
//组装输出对象
|
||||
foreach (var data in ls)
|
||||
List<Dictionary<string, object>> ls = await query.Skip(skip).Take(take).ToDictionaryListAsync();
|
||||
//JNPF.Logging.Log.Debug($"查询数据耗时:{sw.ElapsedMilliseconds}ms");
|
||||
//sw.Restart();
|
||||
|
||||
for (int i = 0; i < ls.Count; i++)
|
||||
{
|
||||
DObject ret = await CombineOutputAsync(vm, new DObject(data), selProps);
|
||||
result.items.Add(ret);
|
||||
result.items.Add(new DObject());
|
||||
}
|
||||
await CombineOutputAsync(ls, result.items, parser);
|
||||
//JNPF.Logging.Log.Debug($"组装返回结果耗时:{sw.ElapsedMilliseconds}ms");
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -239,86 +236,66 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
/// <summary>
|
||||
/// 组装子模型对象
|
||||
/// </summary>
|
||||
/// <param name="vm"></param>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="selProps"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<DObject> CombineOutputAsync(Vmodel vm, DObject src, List<VmSelectProp> selProps)
|
||||
private async Task CombineOutputAsync(List<Dictionary<string, object>> src, List<DObject> dest, VmQueryParser parser)
|
||||
{
|
||||
DObject ret = new();
|
||||
foreach (var prop in selProps)
|
||||
foreach (VmNavigate nav in parser.Navigates.Values)
|
||||
{
|
||||
// 加载主表字段
|
||||
if (prop.navType == eNavigateType.None || prop.navCode == VmSelectProp.MAIN_ALIES)
|
||||
if (nav.path == VmQueryParser.MAIN_ALIES || nav.navConfig.navType == eNavigateType.None)
|
||||
{
|
||||
if (src.ContainsKey(prop.code))
|
||||
foreach (VmSelectProp prop in nav.selects)
|
||||
{
|
||||
ret.Add(prop.code, src[prop.code]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 加载关联表字段
|
||||
if (prop.navType == eNavigateType.OneToOne)
|
||||
{
|
||||
NestedOutput(vm, src, ret, prop);
|
||||
}
|
||||
else if (prop.navType == eNavigateType.OneToMany)
|
||||
{
|
||||
await NestedOneToManyAsync(vm, src, ret, prop, selProps);
|
||||
}
|
||||
else if (prop.navType == eNavigateType.ManyToMany)
|
||||
{
|
||||
if (!ret.ContainsKey(prop.navCode))
|
||||
for (int i = 0; i < src.Count; i++)
|
||||
{
|
||||
ret.Add(prop.navCode, new List<DObject>());
|
||||
dest[i].Add(prop.code, src[i].GetOrDefault(prop.code));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将一对一的关联表字段嵌入到返回值中
|
||||
/// </summary>
|
||||
private void NestedOutput(Vmodel vm, DObject src, DObject ret, VmSelectProp prop)
|
||||
{
|
||||
// 以 nav_prop的形式返回
|
||||
var key = prop.navCode + "_" + prop.code;
|
||||
ret.Add(key, src[key]);
|
||||
// 以 nav.prop的形式返回
|
||||
//if (!ret.ContainsKey(prop.navCode))
|
||||
//{
|
||||
// ret.Add(prop.navCode, new DObject());
|
||||
//}
|
||||
//var key = prop.navCode + "_" + prop.code;
|
||||
//if (src.ContainsKey(key))
|
||||
//{
|
||||
// ((DObject)ret[prop.navCode]).Add(prop.code, src[key]);
|
||||
//}
|
||||
}
|
||||
|
||||
private async Task NestedOneToManyAsync(Vmodel vm, DObject src, DObject ret, VmSelectProp prop, List<VmSelectProp> selProps)
|
||||
{
|
||||
// 在返回值中增加导航属性
|
||||
if (ret.ContainsKey(prop.navCode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
ret.Add(prop.navCode, new List<DObject>());
|
||||
|
||||
// 找到导航属性的配置
|
||||
var navCfg = vm.navProps.First(a => a.code == prop.navCode);
|
||||
if (navCfg != null && navCfg.naviModel != null && src.ContainsKey(navCfg.refField) && navCfg.refCode == VmSelectProp.MAIN_ALIES)
|
||||
{
|
||||
VmListInput input = new VmListInput();
|
||||
var fkProp = navCfg.naviModel.FieldCodeToPropCode(navCfg.fkField);
|
||||
if (!string.IsNullOrEmpty(fkProp))
|
||||
else if (nav.navConfig.navType == eNavigateType.OneToOne)
|
||||
{
|
||||
input.q = new DObject(fkProp, src[navCfg.refField]);
|
||||
input.o = string.Join(',', selProps.Where(a => a.navCode == prop.navCode).Select(a => a.code));
|
||||
ret[prop.navCode] = (await QueryDataAsync(navCfg.naviModel, input)).items;
|
||||
foreach (VmSelectProp prop in nav.selects)
|
||||
{
|
||||
string key = prop.asName.Replace(VmQueryParser.PROP_SEPERATE, VmQueryParser.NAVI_SEPERATE);
|
||||
for (int i = 0; i < src.Count; i++)
|
||||
{
|
||||
dest[i].Add(key, src[i].GetOrDefault(prop.asName));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nav.navConfig.navType == eNavigateType.OneToMany)
|
||||
{
|
||||
object[] ids = new object[] { "in" };
|
||||
ids = ids.Union(dest.Select(a => a.GetOrDefault(nav.navConfig.refProp)).Where(a => a != null)).ToArray();
|
||||
VmQueryInput input = new()
|
||||
{
|
||||
q = new DObject(nav.navConfig.fkProp, ids)
|
||||
};
|
||||
nav.wheres.ForEach(a =>
|
||||
{
|
||||
input.q.Add(a.code, a.value);
|
||||
});
|
||||
input.o = string.Join(',', nav.selects.Select(a => a.code));
|
||||
List<DObject> childs = (await QueryDataAsync(nav.navConfig.naviModel!, input)).items;
|
||||
for (int i = 0; i < dest.Count; i++)
|
||||
{
|
||||
string? fkValue = dest[i][nav.navConfig.refProp]?.ToString();
|
||||
dest[i][nav.pathCode] = childs.Where(a => a[nav.navConfig.fkProp]?.ToString() == fkValue).ToList();
|
||||
}
|
||||
//for (int i = 0; i < src.Count; i++)
|
||||
//{
|
||||
// //dest[i].Add(selectVm.pathCode, new List<DObject>());
|
||||
// if (src[i].ContainsKey(refProp))
|
||||
// {
|
||||
// VmQueryInput input = new VmQueryInput();
|
||||
// input.q = new DObject(fkProp, src[i][refProp]);
|
||||
// nav.wheres.ForEach(a =>
|
||||
// {
|
||||
// input.q.Add(a.code, a.value);
|
||||
// });
|
||||
// input.o = string.Join(',', nav.selects.Select(a => a.code));
|
||||
// dest[i][nav.pathCode] = (await QueryDataAsync(nav.navConfig.naviModel, input)).items;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -333,31 +310,34 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
//新增一条数据
|
||||
if (input.data != null)
|
||||
{
|
||||
var pkey = vm.GetPrimary();
|
||||
var model = vm.ToCreateEntity(input.data, _user);
|
||||
if (pkey.csType == "int" || pkey.csType == "long")
|
||||
VmDbProp pkey = vm.GetPrimary();
|
||||
DObject model = vm.ToCreateEntity(input.data, _user);
|
||||
if (pkey.csType is "int" or "long")
|
||||
{
|
||||
var id = await db.Insertable(model).AS(vm.tableName).ExecuteReturnBigIdentityAsync();
|
||||
if ((long)input.data[pkey.code] != id) input.data[pkey.code] = id;
|
||||
long id = await db.Insertable(model).AS(vm.tableName).ExecuteReturnBigIdentityAsync();
|
||||
if ((long)input.data[pkey.code] != id)
|
||||
{
|
||||
input.data[pkey.code] = id;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await db.Insertable(model).AS(vm.tableName).ExecuteCommandAsync();
|
||||
_ = await db.Insertable(model).AS(vm.tableName).ExecuteCommandAsync();
|
||||
}
|
||||
return input.data;
|
||||
}
|
||||
//批量新增数据
|
||||
else
|
||||
{
|
||||
var pkey = vm.GetPrimary();
|
||||
List<DObject> lst = new List<DObject>();
|
||||
foreach (var item in input.items!)
|
||||
VmDbProp pkey = vm.GetPrimary();
|
||||
List<DObject> lst = new();
|
||||
foreach (DObject item in input.items!)
|
||||
{
|
||||
lst.Add(vm.ToCreateEntity(item, _user));
|
||||
}
|
||||
if (pkey.csType == "int")
|
||||
{
|
||||
var ids = await db.Insertable(lst).AS(vm.tableName).ExecuteReturnPkListAsync<int>();
|
||||
List<int> ids = await db.Insertable(lst).AS(vm.tableName).ExecuteReturnPkListAsync<int>();
|
||||
for (int i = 0; i < input.items.Count; i++)
|
||||
{
|
||||
input.items[i][pkey.code] = ids[i];
|
||||
@@ -365,7 +345,7 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
}
|
||||
else if (pkey.csType == "long")
|
||||
{
|
||||
var ids = await db.Insertable(lst).AS(vm.tableName).ExecuteReturnPkListAsync<long>();
|
||||
List<long> ids = await db.Insertable(lst).AS(vm.tableName).ExecuteReturnPkListAsync<long>();
|
||||
for (int i = 0; i < input.items.Count; i++)
|
||||
{
|
||||
input.items[i][pkey.code] = ids[i];
|
||||
@@ -373,7 +353,7 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
}
|
||||
else
|
||||
{
|
||||
await db.Insertable(lst).AS(vm.tableName).ExecuteCommandAsync();
|
||||
_ = await db.Insertable(lst).AS(vm.tableName).ExecuteCommandAsync();
|
||||
}
|
||||
return input.items;
|
||||
}
|
||||
@@ -392,12 +372,12 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
public async Task<dynamic> UpdateDataAsync(Vmodel vm, VmUpdateInput input)
|
||||
{
|
||||
ISqlSugarClient db = GetSqlSugar(vm.dbCode);
|
||||
var pk = vm.GetPrimary();
|
||||
VmDbProp pk = vm.GetPrimary();
|
||||
int num = 0;
|
||||
//修改一条数据
|
||||
if (input.data != null)
|
||||
{
|
||||
var model = vm.ToUpdateEntity(input.data, _user);
|
||||
DObject model = vm.ToUpdateEntity(input.data, _user);
|
||||
if (!model.ContainsKey(pk.field))
|
||||
{
|
||||
throw new Exception($"更新数据时主键({pk.code})不可为空");
|
||||
@@ -412,9 +392,9 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
else if (input.items != null)
|
||||
{
|
||||
List<DObject> lst = new();
|
||||
foreach (var item in input.items)
|
||||
foreach (DObject item in input.items)
|
||||
{
|
||||
var model = vm.ToUpdateEntity(item, _user);
|
||||
DObject model = vm.ToUpdateEntity(item, _user);
|
||||
if (model.ContainsKey(pk.field))
|
||||
{
|
||||
lst.Add(model);
|
||||
@@ -431,7 +411,7 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||
public async Task<int> DeleteDataAsync(Vmodel vm, VmDeleteInput input)
|
||||
{
|
||||
ISqlSugarClient db = GetSqlSugar(vm.dbCode);
|
||||
var pk = vm.GetPrimary();
|
||||
VmDbProp pk = vm.GetPrimary();
|
||||
int num = 0;
|
||||
List<Dictionary<string, object>> ids = new();
|
||||
if (input.id != null)
|
||||
|
||||
@@ -48,7 +48,7 @@ public interface IDataAccess : ITransient
|
||||
/// <summary>
|
||||
/// 查询数据 默认方法
|
||||
/// </summary>
|
||||
Task<VmPagedOutput> QueryDataAsync(Vmodel vm, VmListInput input);
|
||||
Task<VmPagedOutput> QueryDataAsync(Vmodel vm, VmQueryInput input);
|
||||
|
||||
//Task<dynamic> CreateDataAsync(VmCreateInput input);
|
||||
/// <summary>
|
||||
|
||||
@@ -67,9 +67,9 @@ public class VmGetListInput : VmBaseInput
|
||||
/// </summary>
|
||||
public string o { get; set; } = "*";
|
||||
|
||||
public VmListInput ToListInput()
|
||||
public VmQueryInput ToListInput()
|
||||
{
|
||||
VmListInput arg = this.Adapt<VmListInput>();
|
||||
VmQueryInput arg = this.Adapt<VmQueryInput>();
|
||||
|
||||
if (!string.IsNullOrEmpty(q))
|
||||
{
|
||||
@@ -83,7 +83,7 @@ public class VmGetListInput : VmBaseInput
|
||||
/// <summary>
|
||||
/// 获取多条数据输入参数
|
||||
/// </summary>
|
||||
public class VmListInput : VmGetListInput
|
||||
public class VmQueryInput : VmGetListInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询条件
|
||||
@@ -152,20 +152,20 @@ public class PagedOutput<T>
|
||||
/// <summary>
|
||||
/// 动态分页列表输出对象
|
||||
/// </summary>
|
||||
public class VmPagedOutput : PagedOutput<dynamic>
|
||||
public class VmPagedOutput : PagedOutput<DObject>
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询属性信息
|
||||
/// </summary>
|
||||
public class VmSelectProp
|
||||
{
|
||||
public const string MAIN_ALIES = "m";
|
||||
public string code { get; set; } = string.Empty;
|
||||
public string field { get; set; } = string.Empty;
|
||||
public List<string> navPath { get; set; } = new List<string>();
|
||||
public string navCode { get; set; } = MAIN_ALIES;
|
||||
public ePropType propType { get; set; }
|
||||
public eNavigateType navType { get; set; }
|
||||
}
|
||||
///// <summary>
|
||||
///// 查询属性信息
|
||||
///// </summary>
|
||||
//public class VmSelectProp
|
||||
//{
|
||||
// public const string MAIN_ALIES = "m";
|
||||
// public string code { get; set; } = string.Empty;
|
||||
// public string field { get; set; } = string.Empty;
|
||||
// public List<string> navPath { get; set; } = new List<string>();
|
||||
// public string navCode { get; set; } = MAIN_ALIES;
|
||||
// public ePropType propType { get; set; }
|
||||
// public eNavigateType navType { get; set; }
|
||||
//}
|
||||
@@ -30,7 +30,7 @@ public class VmDbProp : VmBaseProp
|
||||
/// <summary>
|
||||
/// 数据类型
|
||||
/// </summary>
|
||||
public string? csType { get; set; }
|
||||
public string csType { get; set; } = "string";
|
||||
|
||||
/// <summary>
|
||||
/// 长度
|
||||
|
||||
@@ -27,17 +27,17 @@ public class VmNavProp : VmBaseProp
|
||||
/// <summary>
|
||||
/// 源表代码,默认为m,表示与主表关联,可设置为中间表导航属性code,用来表示多对多
|
||||
/// </summary>
|
||||
public string refCode { get; set; } = VmSelectProp.MAIN_ALIES;
|
||||
public string refCode { get; set; } = VmQueryParser.MAIN_ALIES;
|
||||
|
||||
/// <summary>
|
||||
/// 源表字段, 源表的外键字段
|
||||
/// </summary>
|
||||
public string refField { get; set; } = string.Empty;
|
||||
public string refProp { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 导航表字段
|
||||
/// </summary>
|
||||
public string fkField { get; set; } = string.Empty;
|
||||
public string fkProp { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 关联模型
|
||||
|
||||
@@ -1,105 +1,508 @@
|
||||
using JNPF.Common.Extension;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing.Drawing2D;
|
||||
using NPOI.OpenXmlFormats.Dml.Diagram;
|
||||
using SqlSugar;
|
||||
using Tnb.Core;
|
||||
using Tnb.Vengine.DataAccess;
|
||||
|
||||
namespace Tnb.Vengine.Domain
|
||||
namespace Tnb.Vengine.Domain;
|
||||
|
||||
internal class VmQueryParser
|
||||
{
|
||||
public class VmQueryParser
|
||||
public const string MAIN_ALIES = "m";
|
||||
public const char NAVI_SEPERATE = '.';
|
||||
public const char PROP_SEPERATE = '&';
|
||||
|
||||
private readonly IDataAccess _dataAccess;
|
||||
private readonly Vmodel _root;
|
||||
private readonly VmQueryInput _input;
|
||||
|
||||
public Dictionary<string, VmNavigate> Navigates { get; } = new Dictionary<string, VmNavigate>();
|
||||
public VmQueryParser(IDataAccess dataAccess, Vmodel rootModel, VmQueryInput input)
|
||||
{
|
||||
private readonly IDataAccess _dataAccess;
|
||||
private readonly Vmodel _root;
|
||||
private List<string> _outputs;
|
||||
private Dictionary<string, VmSelect> _selectProps = new Dictionary<string, VmSelect>();
|
||||
private Dictionary<string, Vmodel?> _navModels = new Dictionary<string, Vmodel?>();
|
||||
public VmQueryParser(IDataAccess dataAccess, Vmodel rootModel, string output)
|
||||
{
|
||||
_dataAccess = dataAccess;
|
||||
_root = rootModel;
|
||||
ParseOutputStr(output);
|
||||
}
|
||||
/// <summary>
|
||||
/// 按模型组织要输出的属性
|
||||
/// </summary>
|
||||
private void ParseOutputStr(string output)
|
||||
{
|
||||
_outputs = output.Split(',').Distinct().ToList();
|
||||
_selectProps.Add(Vmodel.MAIN_ALIES, new VmSelect() { navModel = _root });
|
||||
foreach (var outStr in _outputs)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(outStr)) continue;
|
||||
var codes = outStr.Split('.');
|
||||
if (codes.Length == 1)
|
||||
{
|
||||
_selectProps[Vmodel.MAIN_ALIES].propCodes.Add(outStr);
|
||||
continue;
|
||||
}
|
||||
var vmPath = "";
|
||||
for (int i = 0; i < codes.Length - 1; i++)
|
||||
{
|
||||
vmPath = i == 0 ? codes[i] : vmPath + "." + codes[i];
|
||||
if (!_selectProps.ContainsKey(vmPath))
|
||||
{
|
||||
_selectProps.Add(vmPath, new VmSelect(vmPath, i + 2));
|
||||
}
|
||||
if (i == codes.Length - 2)
|
||||
{
|
||||
_selectProps[vmPath].propCodes.Add(codes[i + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadNavModel()
|
||||
{
|
||||
var keys = _selectProps.Keys.Where(a => a != Vmodel.MAIN_ALIES).OrderBy(a => a).ToList();
|
||||
foreach (var selVm in _selectProps.Values)
|
||||
{
|
||||
if (_navModels.ContainsKey(selVm.path))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
var navProps = _root.navProps.Where(a => _selectProps.Values.Any(b => b.path.StartsWith(a.code + "."))).ToList();
|
||||
await LoadVmodelNavigateAsync(navProps);
|
||||
}
|
||||
private async Task LoadVmodelNavigateAsync(List<VmNavProp> navProps)
|
||||
{
|
||||
var db = _dataAccess.GetSqlSugar();
|
||||
|
||||
var vmids = navProps.Select(a => a.vmid).Distinct().ToList();
|
||||
var navs = await db.Queryable<Vmodel>().Where(a => vmids.Contains(a.id)).ToDictionaryAsync(a => a.id, a => a);
|
||||
foreach (var navProp in navProps)
|
||||
{
|
||||
navProp.naviModel = (Vmodel)navs.GetOrDefault(navProp.vmid);
|
||||
navProp.naviModel.navProps.Where(a => _selectProps.Values.Any(b => b.path.StartsWith(a.code + "."))).ToList();
|
||||
}
|
||||
}
|
||||
_dataAccess = dataAccess;
|
||||
_root = rootModel;
|
||||
_input = input;
|
||||
}
|
||||
/// <summary>
|
||||
/// 解析查询参数
|
||||
/// </summary>
|
||||
public void ParseQueryInput()
|
||||
{
|
||||
// 初始化根模型
|
||||
Navigates.Clear();
|
||||
VmNavigate main = new(MAIN_ALIES);
|
||||
main.navConfig.naviModel = _root;
|
||||
Navigates.Add(MAIN_ALIES, main);
|
||||
|
||||
ParseOutputStr(_input.o);
|
||||
ParseQueryPara(_input.q);
|
||||
ParseSortPara(_input.sort);
|
||||
}
|
||||
|
||||
internal class VmSelect
|
||||
/// <summary>
|
||||
/// 清除字符串特殊符号
|
||||
/// </summary>
|
||||
private string ClearStr(string str)
|
||||
{
|
||||
public Vmodel? navModel { get; set; }
|
||||
public string path { get; set; } = Vmodel.MAIN_ALIES;
|
||||
public int level { get; set; } = 1;
|
||||
public eNavigateType navType { get; set; } = eNavigateType.None;
|
||||
public List<string> navPaths { get; set; } = new List<string>();
|
||||
return str.Trim(' ', '\r', '\n', '\t');
|
||||
}
|
||||
|
||||
public List<string> propCodes { get; set; } = new List<string>();
|
||||
public List<string> fieldCodes { get; set; } = new List<string>();
|
||||
/// <summary>
|
||||
/// 解析输出属性字符串
|
||||
/// </summary>
|
||||
private void ParseOutputStr(string output)
|
||||
{
|
||||
// t1.t2.id
|
||||
List<string> outputs = output.Split(',').Distinct().ToList();
|
||||
foreach (string? outStr in outputs)
|
||||
{
|
||||
_ = ClearStr(outStr);
|
||||
if (string.IsNullOrWhiteSpace(outStr))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// t1 t2 id
|
||||
string[] codes = outStr.Split(NAVI_SEPERATE);
|
||||
|
||||
public VmSelect()
|
||||
{
|
||||
}
|
||||
public VmSelect(string vmPath, int vmLevel)
|
||||
{
|
||||
path = vmPath;
|
||||
level = vmLevel;
|
||||
// 根据导航路径添加选择器
|
||||
string vmPath = MAIN_ALIES;
|
||||
for (int i = 0; i < codes.Length - 1; i++)
|
||||
{
|
||||
string code = ClearStr(codes[i]);
|
||||
vmPath = i == 0 ? code : vmPath + NAVI_SEPERATE + code;
|
||||
if (!Navigates.ContainsKey(vmPath))
|
||||
{
|
||||
Navigates.Add(vmPath, new VmNavigate(vmPath));
|
||||
}
|
||||
}
|
||||
|
||||
// 添加返回的属性到选择器
|
||||
string lastCode = ClearStr(codes[^1]);
|
||||
Navigates[vmPath].selects.Add(new VmSelectProp(lastCode));
|
||||
}
|
||||
}
|
||||
|
||||
internal class NavigateVmodel
|
||||
/// <summary>
|
||||
/// 解析查询参数
|
||||
/// </summary>
|
||||
private void ParseQueryPara(DObject? query)
|
||||
{
|
||||
public Vmodel? navModel { get; set; }
|
||||
public string navPath { get; set; }
|
||||
if (query == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, object> item in query)
|
||||
{
|
||||
string[] codes = item.Key.Split(NAVI_SEPERATE);
|
||||
|
||||
// 将导航属性查询条件添加到选择器
|
||||
string vmPath = MAIN_ALIES;
|
||||
for (int i = 0; i < codes.Length - 1; i++)
|
||||
{
|
||||
string code = ClearStr(codes[i]);
|
||||
vmPath = i == 0 ? code : vmPath + NAVI_SEPERATE + code;
|
||||
if (!Navigates.ContainsKey(vmPath))
|
||||
{
|
||||
Navigates.Add(vmPath, new VmNavigate(vmPath));
|
||||
}
|
||||
}
|
||||
// 添加返回的属性到选择器
|
||||
string lastCode = ClearStr(codes[^1]);
|
||||
Navigates[vmPath].wheres.Add(new VmWhereProp(lastCode) { value = item.Value });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析排序参数
|
||||
/// </summary>
|
||||
private void ParseSortPara(string? sort)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sort))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string[] orders = sort.Split(',');
|
||||
foreach (string orderStr in orders)
|
||||
{
|
||||
_ = ClearStr(orderStr);
|
||||
if (string.IsNullOrWhiteSpace(orderStr))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// 拆分 m.code desc
|
||||
string[] codes = orderStr.Split(' ', 1);
|
||||
// 拆分 m.code
|
||||
(string?, string) orderPath = codes[0].GetParent(NAVI_SEPERATE);
|
||||
orderPath.Item1 ??= MAIN_ALIES;
|
||||
ThrowIf.When(!Navigates.ContainsKey(orderPath.Item1), $"排序参数{orderStr}错误,导航路径{orderPath.Item1}必须包含在输出参数中");
|
||||
|
||||
VmOrderProp orderby = new(orderPath.Item2);
|
||||
if (codes.Length == 2)
|
||||
{
|
||||
OrderByType? orderType = codes[1].ToLower() switch
|
||||
{
|
||||
"asc" => OrderByType.Asc,
|
||||
"desc" => OrderByType.Desc,
|
||||
_ => null
|
||||
};
|
||||
ThrowIf.IsNull(orderType, $"排序方式{orderStr}不正确");
|
||||
orderby.orderType = orderType.Value;
|
||||
}
|
||||
Navigates[orderPath.Item1].orders.Add(orderby);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载单个导航属性模型
|
||||
/// </summary>
|
||||
private async Task<Vmodel> LoadVmNavigateModelAsync(VmNavigate nav, Dictionary<string, VmNavigate> navs)
|
||||
{
|
||||
if (nav.navConfig.naviModel != null)
|
||||
{
|
||||
return nav.navConfig.naviModel;
|
||||
}
|
||||
|
||||
// 分割导航路径, a.b.c -> a.b, c
|
||||
(string?, string) path = nav.path.GetParent(NAVI_SEPERATE);
|
||||
path.Item1 ??= MAIN_ALIES;
|
||||
nav.parent = Navigates[path.Item1];
|
||||
Vmodel parentVm = await LoadVmNavigateModelAsync(nav.parent, navs);
|
||||
|
||||
// 获取导航属性配置
|
||||
nav.navConfig = parentVm.navProps.FirstOrDefault(a => a.code == path.Item2)!;
|
||||
ThrowIf.IsNull(nav.navConfig, $"模型({parentVm.fullCode})的导航属性{nav.path}配置错误: 找不到(code = {path.Item2})的导航属性");
|
||||
|
||||
// 获取导航模型
|
||||
nav.navConfig.naviModel = await _dataAccess.GetVmodelAsync(nav.navConfig.vmid);
|
||||
ThrowIf.IsNull(nav.navConfig.naviModel, $"模型({parentVm.fullCode})的导航属性{nav.path}配置错误: 找不到(id = {nav.navConfig.vmid})的模型");
|
||||
|
||||
// 处理导航模型
|
||||
if (nav.navConfig.refCode == MAIN_ALIES)
|
||||
{
|
||||
var field = nav.parent.navConfig.naviModel!.PropToFieldCode(nav.navConfig.refProp);
|
||||
ThrowIf.IsNull(field, $"模型({parentVm.fullCode})的导航属性{nav.path}配置错误: 找不到(code = {nav.navConfig.refProp})的字段");
|
||||
field = nav.navConfig.naviModel.PropToFieldCode(nav.navConfig.fkProp);
|
||||
ThrowIf.IsNull(field, $"模型({parentVm.fullCode})的导航属性{nav.path}配置错误: 在子模型{nav.navConfig.naviModel.fullCode}中找不到(code = {nav.navConfig.fkProp})的字段");
|
||||
if (!nav.parent.selects.Any(a => a.code == nav.navConfig.refProp))
|
||||
{
|
||||
nav.parent.selects.Add(new VmSelectProp(nav.navConfig.refProp));
|
||||
}
|
||||
if (!nav.selects.Any(a => a.code == nav.navConfig.fkProp))
|
||||
{
|
||||
nav.selects.Add(new VmSelectProp(nav.navConfig.fkProp));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var navPath = nav.path + NAVI_SEPERATE + nav.navConfig.refCode;
|
||||
if (!Navigates.ContainsKey(navPath))
|
||||
{
|
||||
VmNavigate midNav = new VmNavigate(navPath);
|
||||
midNav.navConfig = parentVm.navProps.FirstOrDefault(a => a.code == nav.navConfig.refCode)!;
|
||||
ThrowIf.IsNull(midNav.navConfig, $"模型({parentVm.fullCode})的导航属性{midNav.path}配置错误: 找不到(code = {nav.navConfig.refCode})的导航属性");
|
||||
midNav.navConfig.naviModel = await _dataAccess.GetVmodelAsync(midNav.navConfig.vmid);
|
||||
ThrowIf.IsNull(midNav.navConfig.naviModel, $"模型({parentVm.fullCode})的导航属性{midNav.path}配置错误: 找不到(id = {midNav.navConfig.vmid})的模型");
|
||||
}
|
||||
}
|
||||
|
||||
return nav.navConfig.naviModel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载单个导航属性模型
|
||||
/// </summary>
|
||||
public async Task LoadNavigateAsync()
|
||||
{
|
||||
Dictionary<string, VmNavigate> tobeAdd = new Dictionary<string, VmNavigate>();
|
||||
foreach (VmNavigate nav in Navigates.Values)
|
||||
{
|
||||
_ = await LoadVmNavigateModelAsync(nav, tobeAdd);
|
||||
}
|
||||
foreach (var item in tobeAdd)
|
||||
{
|
||||
Navigates.Add(item.Key, item.Value);
|
||||
}
|
||||
foreach (VmNavigate nav in Navigates.Values)
|
||||
{
|
||||
nav.HandleStar();
|
||||
nav.LoadDbProp();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理一对一联表关系,生成联表信息
|
||||
/// </summary>
|
||||
/// <param name="selProps"></param>
|
||||
/// <remarks>SELECT * FROM wms_distask_h m INNER JOIN eqp_equipment equip ON m.device_id=equip."id" INNER JOIN eqp_equip_type equipType ON equip.equip_type_id=equipType."id"</remarks>
|
||||
/// <returns></returns>
|
||||
public List<JoinInfoParameter> GetJoinInfos()
|
||||
{
|
||||
List<JoinInfoParameter> joins = new();
|
||||
// 主查询中只处理主表和一对一的联表
|
||||
IEnumerable<VmNavigate> navs = Navigates.Values.Where(a => a.path != MAIN_ALIES && a.navConfig.navType == eNavigateType.OneToOne);
|
||||
foreach (VmNavigate? nav in navs)
|
||||
{
|
||||
Debug.Assert(nav.parent != null && nav.navConfig.naviModel != null);
|
||||
JoinInfoParameter join = new() { TableName = nav.navConfig.naviModel.tableName, ShortName = nav.pathCode, Type = JoinType.Left };
|
||||
var refNav = nav.navConfig.refCode == MAIN_ALIES ? nav.parent : Navigates[nav.path + "." + nav.navConfig.refCode];
|
||||
var fkField = nav.navConfig.naviModel.PropToFieldCode(nav.navConfig.fkProp);
|
||||
var refField = refNav.navConfig.naviModel!.PropToFieldCode(nav.navConfig.refProp);
|
||||
join.Models = ObjectFuncModel.Create("Equals", $"{nav.pathCode}.{fkField}", $"{refNav.pathCode}.{refField}");
|
||||
joins.Add(join);
|
||||
}
|
||||
return joins;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成查询过滤条件
|
||||
/// </summary>
|
||||
/// <param name="filter"></param>
|
||||
/// <returns></returns>
|
||||
public List<IConditionalModel> GetConditionalModels()
|
||||
{
|
||||
List<IConditionalModel> wheres = new();
|
||||
foreach (VmNavigate? nav in Navigates.Values.Where(a => (a.path == MAIN_ALIES || a.navConfig.navType == eNavigateType.OneToOne) && a.wheres.Count > 0))
|
||||
{
|
||||
foreach (VmWhereProp where in nav.wheres)
|
||||
{
|
||||
if (where.value is IEnumerable<object> arrObj)
|
||||
{
|
||||
object[] val = arrObj.ToArray();
|
||||
string op = val[0].ToString()!;
|
||||
switch (op)
|
||||
{
|
||||
case "><":
|
||||
wheres.Add(new ConditionalModel { FieldName = where.fieldName, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThan, CSharpTypeName = where.csType });
|
||||
wheres.Add(new ConditionalModel { FieldName = where.fieldName, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThan, CSharpTypeName = where.csType });
|
||||
break;
|
||||
case ">=<":
|
||||
wheres.Add(new ConditionalModel { FieldName = where.fieldName, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThanOrEqual, CSharpTypeName = where.csType });
|
||||
wheres.Add(new ConditionalModel { FieldName = where.fieldName, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThan, CSharpTypeName = where.csType });
|
||||
break;
|
||||
case "><=":
|
||||
wheres.Add(new ConditionalModel { FieldName = where.fieldName, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThan, CSharpTypeName = where.csType });
|
||||
wheres.Add(new ConditionalModel { FieldName = where.fieldName, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThanOrEqual, CSharpTypeName = where.csType });
|
||||
break;
|
||||
case ">=<=":
|
||||
wheres.Add(new ConditionalModel { FieldName = where.fieldName, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThanOrEqual, CSharpTypeName = where.csType });
|
||||
wheres.Add(new ConditionalModel { FieldName = where.fieldName, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThanOrEqual, CSharpTypeName = where.csType });
|
||||
break;
|
||||
case "in":
|
||||
wheres.Add(new ConditionalModel { FieldName = where.fieldName, FieldValue = string.Join(',', val.Skip(1)), ConditionalType = ConditionalType.In, CSharpTypeName = where.csType });
|
||||
break;
|
||||
default: op = string.Empty; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConditionalType conditionalType = ConditionalType.Equal;
|
||||
string? value = where.value?.ToString();
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value.Length >= 2)
|
||||
{
|
||||
string op = value[..2];
|
||||
switch (op)
|
||||
{
|
||||
case "%%": conditionalType = ConditionalType.Like; break;
|
||||
case ">>": conditionalType = ConditionalType.GreaterThan; break;
|
||||
case "<<": conditionalType = ConditionalType.LessThan; break;
|
||||
case ">=": conditionalType = ConditionalType.GreaterThanOrEqual; break;
|
||||
case "<=": conditionalType = ConditionalType.LessThanOrEqual; break;
|
||||
case "==": conditionalType = ConditionalType.Equal; break;
|
||||
default: op = string.Empty; break;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(op))
|
||||
{
|
||||
value = value.RemovePreFix(op);
|
||||
if (value.ToLower() == "null")
|
||||
{
|
||||
value = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
wheres.Add(new ConditionalModel { FieldName = where.fieldName, FieldValue = value, ConditionalType = conditionalType, CSharpTypeName = where.csType });
|
||||
}
|
||||
}
|
||||
}
|
||||
return wheres;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成按关键字查询的条件列表
|
||||
/// </summary>
|
||||
/// <param name="drill">是否钻取子表关键词查询</param>
|
||||
/// <returns></returns>
|
||||
public ConditionalCollections GetKeywordConditional(bool drill = true)
|
||||
{
|
||||
ConditionalCollections conditionals = new() { ConditionalList = new List<KeyValuePair<WhereType, ConditionalModel>>() };
|
||||
if (string.IsNullOrWhiteSpace(_input.k))
|
||||
{
|
||||
return conditionals;
|
||||
}
|
||||
|
||||
WhereType wType = WhereType.And;
|
||||
IEnumerable<VmNavigate> navs = Navigates.Values.WhereIF(!drill, a => a.path == MAIN_ALIES).Where(a => a.navConfig.navType != eNavigateType.OneToMany);
|
||||
foreach (VmNavigate? nav in navs)
|
||||
{
|
||||
foreach (VmSelectProp? prop in nav.selects.Where(a => a.fuzzy))
|
||||
{
|
||||
conditionals.ConditionalList.Add(new(wType, new ConditionalModel() { FieldName = prop.fieldName, ConditionalType = ConditionalType.Like, FieldValue = _input.k, CSharpTypeName = prop.csType }));
|
||||
wType = WhereType.Or;
|
||||
}
|
||||
}
|
||||
return conditionals;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成排序条件列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<OrderByModel> GetOrderByModels()
|
||||
{
|
||||
IEnumerable<VmNavigate> navs = Navigates.Values.Where(a => a.orders.Count > 0);
|
||||
return navs.SelectMany(a =>
|
||||
{
|
||||
return a.orders.Select(b => new OrderByModel
|
||||
{
|
||||
FieldName = b.fieldName,
|
||||
OrderByType = b.orderType
|
||||
});
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成查询字段列表
|
||||
/// </summary>
|
||||
/// <param name="selProps"></param>
|
||||
/// <returns></returns>
|
||||
public List<SelectModel> GetSelectModels()
|
||||
{
|
||||
IEnumerable<VmNavigate> navs = Navigates.Values.Where(a => (a.path == MAIN_ALIES || a.navConfig.navType == eNavigateType.OneToOne) && a.selects.Count > 0);
|
||||
return navs.SelectMany(a =>
|
||||
{
|
||||
return a.selects.Select(b => new SelectModel
|
||||
{
|
||||
FiledName = b.fieldName,
|
||||
AsName = (a.path == MAIN_ALIES ? "" : a.pathCode + PROP_SEPERATE) + b.code
|
||||
});
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class VmNavigate
|
||||
{
|
||||
public VmNavigate? parent { get; set; }
|
||||
public VmNavProp navConfig { get; set; } = new VmNavProp();
|
||||
public string path { get; set; }
|
||||
public string pathCode { get; set; }
|
||||
|
||||
public List<VmSelectProp> selects { get; set; } = new List<VmSelectProp>();
|
||||
public List<VmWhereProp> wheres { get; set; } = new List<VmWhereProp>();
|
||||
public List<VmOrderProp> orders { get; set; } = new List<VmOrderProp>();
|
||||
|
||||
public VmNavigate(string vmPath)
|
||||
{
|
||||
path = vmPath;
|
||||
pathCode = vmPath.Replace(VmQueryParser.NAVI_SEPERATE, VmQueryParser.PROP_SEPERATE);
|
||||
}
|
||||
/// <summary>
|
||||
/// 处理占位符星号
|
||||
/// </summary>
|
||||
public void HandleStar()
|
||||
{
|
||||
if (selects.Any(a => a.code == "*"))
|
||||
{
|
||||
selects.Clear();
|
||||
navConfig.naviModel!.dbProps.ForEach(a =>
|
||||
{
|
||||
selects.Add(new VmSelectProp(a.code));
|
||||
});
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 将属性名转换为字段名
|
||||
/// </summary>
|
||||
public void LoadDbProp()
|
||||
{
|
||||
foreach (VmSelectProp item in selects)
|
||||
{
|
||||
VmDbProp? prop = navConfig.naviModel!.GetDbProp(item.code);
|
||||
ThrowIf.IsNull(prop, $"输出参数{path}.{item.code}错误: 在模型{navConfig.naviModel.fullCode}中找不到属性({item.code})对应的字段");
|
||||
item.field = prop.field;
|
||||
item.fieldName = pathCode + "." + item.field;
|
||||
item.fuzzy = prop.fuzzy;
|
||||
item.csType = prop.csType;
|
||||
item.asName = (path == VmQueryParser.MAIN_ALIES ? "" : pathCode + VmQueryParser.PROP_SEPERATE) + item.code;
|
||||
}
|
||||
foreach (VmOrderProp item in orders)
|
||||
{
|
||||
VmDbProp? prop = navConfig.naviModel!.GetDbProp(item.code);
|
||||
ThrowIf.IsNull(prop, $"排序参数{path}.{item.code}错误: 在模型{navConfig.naviModel.fullCode}中找不到属性({item.code})对应的字段");
|
||||
item.field = prop.field;
|
||||
item.fieldName = pathCode + "." + item.field;
|
||||
}
|
||||
foreach (VmWhereProp item in wheres)
|
||||
{
|
||||
VmDbProp? prop = navConfig.naviModel!.GetDbProp(item.code);
|
||||
ThrowIf.IsNull(prop, $"查询参数{path}.{item.code}错误: 在模型{navConfig.naviModel.fullCode}中找不到属性({item.code})对应的字段");
|
||||
item.field = prop.field;
|
||||
item.fieldName = pathCode + "." + item.field;
|
||||
item.csType = prop.csType;
|
||||
}
|
||||
//props.RemoveAll(a => string.IsNullOrEmpty(a.field));
|
||||
}
|
||||
}
|
||||
|
||||
internal class VmQueryBaseProp
|
||||
{
|
||||
public string code { get; set; }
|
||||
public string field { get; set; } = string.Empty;
|
||||
public string fieldName { get; set; } = string.Empty;
|
||||
|
||||
public VmQueryBaseProp(string code)
|
||||
{
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class VmSelectProp : VmQueryBaseProp
|
||||
{
|
||||
public string asName { get; set; } = string.Empty;
|
||||
public string csType { get; set; } = "string";
|
||||
public bool fuzzy { get; set; }
|
||||
|
||||
public VmSelectProp(string code) : base(code)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
internal class VmOrderProp : VmQueryBaseProp
|
||||
{
|
||||
public OrderByType orderType { get; set; } = OrderByType.Asc;
|
||||
|
||||
public VmOrderProp(string code) : base(code)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
internal class VmWhereProp : VmQueryBaseProp
|
||||
{
|
||||
public string csType { get; set; } = "string";
|
||||
[AllowNull]
|
||||
public object value { get; set; }
|
||||
|
||||
public VmWhereProp(string code) : base(code)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ namespace Tnb.Vengine.Domain;
|
||||
[SugarTable("sys_vmodel")]
|
||||
public partial class Vmodel : Entity
|
||||
{
|
||||
public const string MAIN_ALIES = "m";
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
@@ -139,9 +137,6 @@ public partial class Vmodel : Entity
|
||||
public string fullCode
|
||||
{ get { return areaCode + "/" + vmCode; } }
|
||||
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public Vmodel? parent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
@@ -151,8 +146,8 @@ public partial class Vmodel : Entity
|
||||
}
|
||||
|
||||
#endregion Properties
|
||||
//private Dictionary<string, string>? _mapField2Prop = null;
|
||||
//private Dictionary<string, string>? _mapProp2Field = null;
|
||||
|
||||
private Dictionary<string, VmDbProp>? _mapProps = null;
|
||||
/// <summary>
|
||||
/// 通过实体创建模型
|
||||
/// </summary>
|
||||
@@ -207,43 +202,13 @@ public partial class Vmodel : Entity
|
||||
/// </summary>
|
||||
/// <param name="propCode"></param>
|
||||
/// <returns></returns>
|
||||
public string? PropCodeToFieldCode(string propCode)
|
||||
public string? PropToFieldCode(string propCode)
|
||||
{
|
||||
return dbProps.Where(a => a.code == propCode).Select(a => a.field).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据字段名获取属性名
|
||||
/// </summary>
|
||||
/// <param name="fieldCode"></param>
|
||||
/// <returns></returns>
|
||||
public string? FieldCodeToPropCode(string fieldCode)
|
||||
{
|
||||
return dbProps.Where(a => a.field == fieldCode).Select(a => a.code).FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 属性代码转换为字段代码
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="ignoreNotMapped"></param>
|
||||
/// <returns></returns>
|
||||
public DObject PropToField(DObject input, bool ignoreNotMapped = true)
|
||||
{
|
||||
DObject ret = new();
|
||||
foreach (var item in input)
|
||||
if(_mapProps == null)
|
||||
{
|
||||
var fcode = PropCodeToFieldCode(item.Key);
|
||||
if (!string.IsNullOrEmpty(fcode))
|
||||
{
|
||||
ret.Add(fcode, item.Value);
|
||||
}
|
||||
else if (!ignoreNotMapped)
|
||||
{
|
||||
ret.Add(item.Key, item.Value);
|
||||
}
|
||||
_mapProps = dbProps.ToDictionary(a=>a.code);
|
||||
}
|
||||
return ret;
|
||||
return _mapProps.GetOrDefault(propCode)?.field;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -252,214 +217,13 @@ public partial class Vmodel : Entity
|
||||
/// <param name="input"></param>
|
||||
/// <param name="ignoreNotMapped"></param>
|
||||
/// <returns></returns>
|
||||
public DObject FieldToProp(DObject input, bool ignoreNotMapped = true)
|
||||
public VmDbProp? GetDbProp(string propCode)
|
||||
{
|
||||
DObject ret = new();
|
||||
foreach (var item in input)
|
||||
if (_mapProps == null)
|
||||
{
|
||||
var pcode = FieldCodeToPropCode(item.Key);
|
||||
if (!string.IsNullOrEmpty(pcode))
|
||||
{
|
||||
ret.Add(pcode, item.Value);
|
||||
}
|
||||
else if (!ignoreNotMapped)
|
||||
{
|
||||
ret.Add(item.Key, item.Value);
|
||||
}
|
||||
_mapProps = dbProps.ToDictionary(a => a.code);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取查询字段的属性信息
|
||||
/// </summary>
|
||||
/// <param name="outputProps"></param>
|
||||
/// <returns></returns>
|
||||
public List<VmSelectProp> GetVmSelectProps(string? outputProps)
|
||||
{
|
||||
if (string.IsNullOrEmpty(outputProps) || outputProps == "*")
|
||||
{
|
||||
return dbProps.Select(a => new VmSelectProp { code = a.code, field = a.field }).ToList();
|
||||
}
|
||||
List<VmSelectProp> selProps = new();
|
||||
var outputs = outputProps.Split(',').Distinct().ToList();
|
||||
foreach (var propCode in outputs)
|
||||
{
|
||||
if (!propCode.Contains("."))
|
||||
{
|
||||
var fieldCode = PropCodeToFieldCode(propCode);
|
||||
if (!string.IsNullOrEmpty(fieldCode))
|
||||
{
|
||||
selProps.Add(new VmSelectProp { code = propCode, field = fieldCode });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
var codes = propCode.Split('.');
|
||||
if (codes.Length != 2) continue;
|
||||
if (codes[0] == VmSelectProp.MAIN_ALIES)
|
||||
{
|
||||
var fieldCode = PropCodeToFieldCode(propCode);
|
||||
if (!string.IsNullOrEmpty(fieldCode))
|
||||
{
|
||||
selProps.Add(new VmSelectProp { code = propCode, field = fieldCode });
|
||||
}
|
||||
continue;
|
||||
}
|
||||
var navProp = navProps.FirstOrDefault(a => a.code == codes[0]);
|
||||
if (navProp?.naviModel != null)
|
||||
{
|
||||
var fieldCode = navProp.naviModel.PropCodeToFieldCode(codes[1]);
|
||||
if (!string.IsNullOrEmpty(fieldCode))
|
||||
{
|
||||
selProps.Add(new VmSelectProp { code = codes[1], field = fieldCode, navCode = codes[0], propType = ePropType.Navigate, navType = navProp.navType });
|
||||
}
|
||||
}
|
||||
}
|
||||
return selProps;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取联表配置信息
|
||||
/// </summary>
|
||||
/// <param name="selProps"></param>
|
||||
/// <returns></returns>
|
||||
public List<JoinInfoParameter> GetJoinInfos(List<VmSelectProp> selProps)
|
||||
{
|
||||
var navigates = selProps.Where(a => a.propType == ePropType.Navigate).Select(a => a.navCode).Distinct().ToList();
|
||||
List<JoinInfoParameter> joins = new();
|
||||
foreach (var navCode in navigates)
|
||||
{
|
||||
if (navCode == VmSelectProp.MAIN_ALIES) continue;
|
||||
var navProp = navProps.First(a => a.code == navCode);
|
||||
if (navProp.naviModel == null || navProp.navType != eNavigateType.OneToOne) continue;
|
||||
JoinInfoParameter join = new JoinInfoParameter { TableName = navProp.naviModel.tableName, ShortName = navCode, Type = JoinType.Left };
|
||||
var fkField = navProp.naviModel.PropCodeToFieldCode(navProp.fkField);
|
||||
var refField = navProp.refField;
|
||||
if (navProp.refCode != VmSelectProp.MAIN_ALIES)
|
||||
{
|
||||
var refProp = navProps.First(a => a.code == navProp.refCode);
|
||||
refField = refProp.naviModel!.PropCodeToFieldCode(navProp.refField);
|
||||
}
|
||||
join.Models = ObjectFuncModel.Create("Equals", $"{navCode}.{fkField}", $"{navProp.refCode}.{refField}");
|
||||
joins.Add(join);
|
||||
}
|
||||
return joins;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为查询过滤条件
|
||||
/// </summary>
|
||||
/// <param name="filter"></param>
|
||||
/// <returns></returns>
|
||||
public List<IConditionalModel> GetConditionalModels(DObject? filter)
|
||||
{
|
||||
List<IConditionalModel> wheres = new List<IConditionalModel>();
|
||||
if (filter == null) return wheres;
|
||||
foreach (var item in filter)
|
||||
{
|
||||
VmDbProp? prop = null;
|
||||
// TODO 按子表条件查询
|
||||
if (item.Key.Contains("."))
|
||||
{
|
||||
var codes = item.Key.Split('.');
|
||||
if (codes.Length >= 2)
|
||||
{
|
||||
var navProp = navProps.FirstOrDefault(a => a.code == codes[0]);
|
||||
if (navProp != null && navProp.naviModel != null)
|
||||
{
|
||||
var dbProp = navProp.naviModel.dbProps.FirstOrDefault(a => a.code == codes[1]);
|
||||
if (dbProp != null)
|
||||
{
|
||||
prop = new VmDbProp();
|
||||
prop.field = codes[0] + "." + dbProp.field;
|
||||
prop.csType = dbProp.csType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prop = dbProps.FirstOrDefault(a => a.code == item.Key);
|
||||
}
|
||||
if (prop == null) continue;
|
||||
if (item.Value is JArray val)
|
||||
{
|
||||
var op = val[0].ToString();
|
||||
switch (op)
|
||||
{
|
||||
case "><":
|
||||
wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThan, CSharpTypeName = prop.csType });
|
||||
wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThan, CSharpTypeName = prop.csType });
|
||||
break;
|
||||
|
||||
case ">=<":
|
||||
wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThanOrEqual, CSharpTypeName = prop.csType });
|
||||
wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThan, CSharpTypeName = prop.csType });
|
||||
break;
|
||||
|
||||
case "><=":
|
||||
wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThan, CSharpTypeName = prop.csType });
|
||||
wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThanOrEqual, CSharpTypeName = prop.csType });
|
||||
break;
|
||||
|
||||
case ">=<=":
|
||||
wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[1].ToString(), ConditionalType = ConditionalType.GreaterThanOrEqual, CSharpTypeName = prop.csType });
|
||||
wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val[2].ToString(), ConditionalType = ConditionalType.LessThanOrEqual, CSharpTypeName = prop.csType });
|
||||
break;
|
||||
|
||||
case "in":
|
||||
wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = val.Skip(1).ToString(), ConditionalType = ConditionalType.In, CSharpTypeName = prop.csType });
|
||||
break;
|
||||
|
||||
default: op = string.Empty; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (item.Value == null) continue;
|
||||
var conditionalType = ConditionalType.Equal;
|
||||
string? value = item.Value?.ToString();
|
||||
if (string.IsNullOrEmpty(value)) continue;
|
||||
if (value.Length >= 2)
|
||||
{
|
||||
var op = value.Substring(0, 2);
|
||||
switch (op)
|
||||
{
|
||||
case "%%": conditionalType = ConditionalType.Like; break;
|
||||
case ">>": conditionalType = ConditionalType.GreaterThan; break;
|
||||
case "<<": conditionalType = ConditionalType.LessThan; break;
|
||||
case ">=": conditionalType = ConditionalType.GreaterThanOrEqual; break;
|
||||
case "<=": conditionalType = ConditionalType.LessThanOrEqual; break;
|
||||
case "==": conditionalType = ConditionalType.Equal; break;
|
||||
default: op = string.Empty; break;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(op))
|
||||
{
|
||||
value = value.RemovePreFix(op);
|
||||
if (value.ToLower() == "null")
|
||||
{
|
||||
value = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
wheres.Add(new ConditionalModel { FieldName = prop.field, FieldValue = value, ConditionalType = conditionalType, CSharpTypeName = prop.csType });
|
||||
}
|
||||
}
|
||||
return wheres;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为查询字段列表
|
||||
/// </summary>
|
||||
/// <param name="selProps"></param>
|
||||
/// <returns></returns>
|
||||
public List<SelectModel> GetSelectModels(List<VmSelectProp> selProps)
|
||||
{
|
||||
return selProps.Where(a => a.navType != eNavigateType.OneToMany && a.navType != eNavigateType.ManyToMany).Select(a => new SelectModel
|
||||
{
|
||||
FiledName = a.navCode + "." + a.field,
|
||||
AsName = (a.navCode == VmSelectProp.MAIN_ALIES ? "" : a.navCode + "_") + a.code
|
||||
}).ToList();
|
||||
return _mapProps.GetOrDefault(propCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -15,11 +15,11 @@ public class VmodelMapper : IRegister
|
||||
{
|
||||
public void Register(TypeAdapterConfig config)
|
||||
{
|
||||
config.ForType<VmGetInput, VmListInput>()
|
||||
config.ForType<VmGetInput, VmQueryInput>()
|
||||
.Map(dest => dest.psize, src => 1)
|
||||
.Map(dest => dest.pnum, src => 0)
|
||||
.Map(dest => dest.q, src => string.IsNullOrEmpty(src.q) ? null : src.q.ToObject<DObject>());
|
||||
config.ForType<VmGetListInput, VmListInput>()
|
||||
config.ForType<VmGetListInput, VmQueryInput>()
|
||||
.Map(dest => dest.q, src => string.IsNullOrEmpty(src.q) ? null : src.q.ToObject<DObject>());
|
||||
config.ForType<DbColumnInfo, VmDbProp>()
|
||||
.Map(dest => dest.code, src => src.DbColumnName.ToCamel())
|
||||
|
||||
Reference in New Issue
Block a user