From cacf9745273056b1101f0181d6abf3be545e22ef Mon Sep 17 00:00:00 2001 From: "fei.pan" Date: Thu, 9 Nov 2023 10:21:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E9=80=9A=E7=94=A8=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3List=E6=94=B9=E4=B8=BA=E7=94=A8left=20join?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Directory.Build.props | 3 + .../Extension/TnbStringExtensions.cs | 8 ++- visualdev/Tnb.Vengine/Domain/VmQueryParser.cs | 63 ++++++++++--------- visualdev/Tnb.Vengine/Domain/Vmodel.cs | 2 +- 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index a363d7b9..a78d6df4 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -3,6 +3,9 @@ $(MSBuildThisFileDirectory) latest $(NoWarn);CS1570;CS1587;CS1591;CS8601;CS8602;CS8603;CS8618; + enable + enable + diff --git a/common/Tnb.Common/Extension/TnbStringExtensions.cs b/common/Tnb.Common/Extension/TnbStringExtensions.cs index 25e9d5d8..c6412e97 100644 --- a/common/Tnb.Common/Extension/TnbStringExtensions.cs +++ b/common/Tnb.Common/Extension/TnbStringExtensions.cs @@ -184,7 +184,10 @@ public static class StringExtensions #endregion - public static (string, string) LastSplit(this string str, char seperate) + /// + /// 查找路径的上一级 + /// + public static (string?, string) LastSplitOnce(this string str, char seperate) { int n = str.LastIndexOf(seperate); if (n > 0) @@ -193,7 +196,8 @@ public static class StringExtensions } else { - return (str, null); + return (null, str); } } + } \ No newline at end of file diff --git a/visualdev/Tnb.Vengine/Domain/VmQueryParser.cs b/visualdev/Tnb.Vengine/Domain/VmQueryParser.cs index dc1729f7..5f698831 100644 --- a/visualdev/Tnb.Vengine/Domain/VmQueryParser.cs +++ b/visualdev/Tnb.Vengine/Domain/VmQueryParser.cs @@ -8,52 +8,57 @@ namespace Tnb.Vengine.Domain private readonly IDataAccess _dataAccess; private readonly Vmodel _root; private List _outputs; - private Dictionary _selectProps = new Dictionary(); + private Dictionary _selectProps = new Dictionary(); private Dictionary _navModels = new Dictionary(); public VmQueryParser(IDataAccess dataAccess, Vmodel rootModel, string output) { _dataAccess = dataAccess; _root = rootModel; - _outputs = output.Split(',').Distinct().ToList(); - ParseOutputStr(); + ParseOutputStr(output); } /// /// 按模型组织要输出的属性 /// - private void ParseOutputStr() + 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)) + if (string.IsNullOrWhiteSpace(outStr)) continue; + var codes = outStr.Split('.'); + if (codes.Length == 1) { + _selectProps[Vmodel.MAIN_ALIES].propCodes.Add(outStr); continue; } - string vmPath; - int n = outStr.LastIndexOf('.'); - if (n < 1) + var vmPath = ""; + for (int i = 0; i < codes.Length - 1; i++) { - vmPath = Vmodel.MAIN_ALIES; + 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]); + } } - else - { - vmPath = outStr.Substring(0, n); - } - if (!_selectProps.ContainsKey(vmPath)) - { - _selectProps.Add(vmPath, new OutputSelect { navPaths = vmPath.Split(',').ToList(), vmPath = vmPath }); - } - var outSelect = _selectProps[vmPath]; - outSelect.propCodes.Add(outStr.Substring(n + 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(selVm.navModel != null) + if (_navModels.ContainsKey(selVm.path)) + { + continue; + } } - var navProps = _root.navProps.Where(a => _selectProps.Values.Any(b => b.vmPath.StartsWith(a.code + "."))).ToList(); + var navProps = _root.navProps.Where(a => _selectProps.Values.Any(b => b.path.StartsWith(a.code + "."))).ToList(); await LoadVmodelNavigateAsync(navProps); } private async Task LoadVmodelNavigateAsync(List navProps) @@ -65,30 +70,30 @@ namespace Tnb.Vengine.Domain foreach (var navProp in navProps) { navProp.naviModel = (Vmodel)navs.GetOrDefault(navProp.vmid); - navProp.naviModel.navProps.Where(a => _selectProps.Values.Any(b => b.vmPath.StartsWith(a.code + "."))).ToList(); + navProp.naviModel.navProps.Where(a => _selectProps.Values.Any(b => b.path.StartsWith(a.code + "."))).ToList(); } } } - internal class OutputSelect + internal class VmSelect { public Vmodel? navModel { get; set; } - public string navPath { get; set; } = string.Empty; - public string vmPath { get; set; } = string.Empty; + public string path { get; set; } = Vmodel.MAIN_ALIES; + public int level { get; set; } = 1; public eNavigateType navType { get; set; } = eNavigateType.None; public List navPaths { get; set; } = new List(); public List propCodes { get; set; } = new List(); public List fieldCodes { get; set; } = new List(); - public OutputSelect() + public VmSelect() { - } - public OutputSelect(Vmodel model) + public VmSelect(string vmPath, int vmLevel) { - vmPath = Vmodel.MAIN_ALIES; + path = vmPath; + level = vmLevel; } } diff --git a/visualdev/Tnb.Vengine/Domain/Vmodel.cs b/visualdev/Tnb.Vengine/Domain/Vmodel.cs index 070ce510..23198e81 100644 --- a/visualdev/Tnb.Vengine/Domain/Vmodel.cs +++ b/visualdev/Tnb.Vengine/Domain/Vmodel.cs @@ -332,7 +332,7 @@ public partial class Vmodel : Entity 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.Inner }; + 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)