private async ValueTask LoopLoadEntitySets(SqlStore db, Entity owner, DbTransaction txn) { if (Expression.Type != ExpressionType.EntitySetExpression) { return; } //判断是否已经生成加载命令 var setmm = (EntitySetModel)owner.Model.GetMember(MemberExpression.Name, true); var setModel = await Runtime.RuntimeContext.Current.GetModelAsync <EntityModel>(setmm.RefModelId); if (_loadEntitySetCmd == null) { var fkmm = (EntityRefModel)setModel.GetMember(setmm.RefMemberId, true); SqlQuery q = new SqlQuery(this); //生成条件 for (int i = 0; i < fkmm.FKMemberIds.Length; i++) { //外键字段 == 当前主键字段 var fkExp = q.T[setModel.GetMember(fkmm.FKMemberIds[i], true).Name]; //var pkValue = owner.GetMember(owner.Model.SqlStoreOptions.PrimaryKeys[i].MemberId).BoxedValue; q.AndWhere(fkExp == new DbParameterExpression()); } //AddSelects SqlQuery.AddAllSelects(q, setModel, ((EntitySetExpression)Expression).RootEntityExpression, null); await AddSelects(q, setModel); _loadEntitySetCmd = db.BuildQuery(q); } //重设加载命令外键参数值为主键值 for (int i = 0; i < owner.Model.SqlStoreOptions.PrimaryKeys.Count; i++) { var pkValue = owner.GetMember(owner.Model.SqlStoreOptions.PrimaryKeys[i].MemberId).BoxedValue; _loadEntitySetCmd.Parameters[i].Value = pkValue; } //开始执行sql加载 using var conn = db.MakeConnection(); //TODO:暂每次new SqlConnection await conn.OpenAsync(); _loadEntitySetCmd.Connection = conn; Log.Debug(_loadEntitySetCmd.CommandText); using var reader = await _loadEntitySetCmd.ExecuteReaderAsync(); var list = new EntityList(setModel.Id); while (await reader.ReadAsync()) { Entity obj = SqlQuery.FillEntity(setModel, reader); list.Add(obj); } InitEntitySetForLoad(owner, setmm, list); //继续加载子级 await LoadEntitySets(db, list, txn); }
/// <summary> /// To the tree node path. /// </summary> /// <returns>注意:可能返回Null</returns> /// <param name="parentMember">Parent member.</param> public async Task <TreeNodePath> ToTreeNodePathAsync(MemberExpression parentMember, Expression displayText) { //TODO:目前实现仅支持单一主键且为Guid的树状结构 //TODO:验证parentMember为EntityExpression,且非聚合引用,且引用目标为自身 var parent = parentMember as EntityExpression; if (Expression.IsNull(parent)) { throw new ArgumentException("parentMember must be EntityRef", nameof(parentMember)); } var model = await RuntimeContext.Current.GetModelAsync <EntityModel>(T.ModelID); var parentModel = (EntityRefModel)model.GetMember(parent.Name, true); if (parentModel.IsAggregationRef) { throw new ArgumentException("can not be AggregationRef", nameof(parentMember)); } if (parentModel.RefModelIds[0] != model.Id) { throw new ArgumentException("must be self-ref", nameof(parentMember)); } var pkName = model.GetMember(model.SqlStoreOptions.PrimaryKeys[0].MemberId, true).Name; var fkName = model.GetMember(parentModel.FKMemberIds[0], true).Name; Purpose = QueryPurpose.ToTreeNodePath; AddSelectItem(new SqlSelectItemExpression(T[pkName])); AddSelectItem(new SqlSelectItemExpression(T[fkName], "ParentId")); AddSelectItem(new SqlSelectItemExpression(displayText, "Text")); var db = SqlStore.Get(model.SqlStoreOptions.StoreModelId); using var cmd = db.BuildQuery(this); using var conn = db.MakeConnection(); await conn.OpenAsync(); cmd.Connection = conn; Log.Debug(cmd.CommandText); var list = new List <TreeNodeInfo>(); using var reader = await cmd.ExecuteReaderAsync(); while (await reader.ReadAsync()) { list.Add(new TreeNodeInfo() { ID = reader.GetGuid(0), Text = reader.GetString(2) }); } return(new TreeNodePath(list)); }
internal async ValueTask LoadEntitySets(SqlStore db, Entity owner, DbTransaction txn) { if (Childs == null) { return; } for (int i = 0; i < Childs.Count; i++) { await Childs[i].LoopLoadEntitySets(db, owner, txn); } }
/// <summary> /// 动态查询,返回匿名类列表 /// </summary> public async Task <IList <TResult> > ToListAsync <TResult>(Func <SqlRowReader, TResult> selector, params SqlSelectItem[] selectItem) { if (selectItem == null || selectItem.Length <= 0) { throw new ArgumentException("must select some one"); } //if (SkipSize > -1 && !HasSortItems) // throw new ArgumentException("Paged query must has sort items."); //TODO:加入默认主键排序 Purpose = QueryPurpose.ToDataTable; if (_selects != null) { _selects.Clear(); } for (int i = 0; i < selectItem.Length; i++) { AddSelectItem(selectItem[i].Target); } //递交查询 var model = await RuntimeContext.Current.GetModelAsync <EntityModel>(T.ModelID); var db = SqlStore.Get(model.SqlStoreOptions.StoreModelId); using var cmd = db.BuildQuery(this); using var conn = db.MakeConnection(); await conn.OpenAsync(); cmd.Connection = conn; Log.Debug(cmd.CommandText); var list = new List <TResult>(); try { using var reader = await cmd.ExecuteReaderAsync(); SqlRowReader rr = new SqlRowReader(reader); while (await reader.ReadAsync()) { list.Add(selector(rr)); } } catch (Exception ex) { Log.Warn($"Exec sql error: {ex.Message}\n{cmd.CommandText}"); throw; } return(list); }
internal async ValueTask LoadEntitySets(SqlStore db, EntityList list, DbTransaction txn) { if (Childs == null) { return; } if (!Childs.Any(t => t.Expression.Type == ExpressionType.EntitySetExpression)) { return; } //TODO:考虑一次加载方案 for (int i = 0; i < list.Count; i++) { await LoadEntitySets(db, list[i], txn); //TODO: fix txn } }
public async Task <int> CountAsync() { Purpose = QueryPurpose.Count; var model = await RuntimeContext.Current.GetModelAsync <EntityModel>(T.ModelID); var db = SqlStore.Get(model.SqlStoreOptions.StoreModelId); var cmd = db.BuildQuery(this); using var conn = db.MakeConnection(); await conn.OpenAsync(); cmd.Connection = conn; Log.Debug(cmd.CommandText); using var reader = await cmd.ExecuteReaderAsync(); if (!await reader.ReadAsync()) { return(0); } return(reader.GetInt32(0)); }
public async Task <Entity> ToSingleAsync() { Purpose = QueryPurpose.ToSingleEntity; //添加选择项 var model = await RuntimeContext.Current.GetModelAsync <EntityModel>(T.ModelID); AddAllSelects(this, model, T, null); if (_rootIncluder != null) { await _rootIncluder.AddSelects(this, model); } //递交查询 var db = SqlStore.Get(model.SqlStoreOptions.StoreModelId); var cmd = db.BuildQuery(this); using var conn = db.MakeConnection(); await conn.OpenAsync(); cmd.Connection = conn; Log.Debug(cmd.CommandText); using var reader = await cmd.ExecuteReaderAsync(); Entity res = null; if (await reader.ReadAsync()) { res = FillEntity(model, reader); } if (_rootIncluder != null) { await _rootIncluder.LoadEntitySets(db, res, null); //TODO:fix txn } return(res); }
public async Task <EntityList> ToListAsync() { Purpose = QueryPurpose.ToEntityList; //添加选择项 var model = await RuntimeContext.Current.GetModelAsync <EntityModel>(T.ModelID); AddAllSelects(this, model, T, null); if (_rootIncluder != null) { await _rootIncluder.AddSelects(this, model); } var db = SqlStore.Get(model.SqlStoreOptions.StoreModelId); var list = new EntityList(T.ModelID); using var cmd = db.BuildQuery(this); using var conn = db.MakeConnection(); await conn.OpenAsync(); cmd.Connection = conn; Log.Debug(cmd.CommandText); using var reader = await cmd.ExecuteReaderAsync(); while (await reader.ReadAsync()) { list.Add(FillEntity(model, reader)); } if (_rootIncluder != null && list != null) { await _rootIncluder.LoadEntitySets(db, list, null); //TODO:fix txn } return(list); }
/// <summary> /// 返回树状结构的实体集合 /// </summary> /// <param name="childrenMember">例:q.T["SubItems"]</param> /// <returns></returns> public async Task <EntityList> ToTreeListAsync(MemberExpression childrenMember) { //TODO:目前实现仅支持单一主键且为Guid的树状结构 Debug.Assert(ReferenceEquals(childrenMember.Owner, T)); var children = (EntitySetExpression)childrenMember; EntityModel model = await RuntimeContext.Current.GetModelAsync <EntityModel>(T.ModelID); EntitySetModel childrenModel = (EntitySetModel)model.GetMember(children.Name, true); EntityRefModel parentModel = (EntityRefModel)model.GetMember(childrenModel.RefMemberId, true); DataFieldModel parentIdModel = (DataFieldModel)model.GetMember(parentModel.FKMemberIds[0], true); TreeParentIDMember = (FieldExpression)T[parentIdModel.Name]; var pk = model.SqlStoreOptions.PrimaryKeys[0].MemberId; AddAllSelects(this, model, T, null); //TODO:加入自动排序 //if (!string.IsNullOrEmpty(setmodel.RefRowNumberMemberName)) //{ // SqlSortItem sort = new SqlSortItem(T[setmodel.RefRowNumberMemberName], SortType.ASC); // SortItems.Insert(0, sort); //} //如果没有设置任何条件,则设置默认条件为查询根级开始 if (Equals(null, Filter)) { Filter = TreeParentIDMember == null; } Purpose = QueryPurpose.ToEntityTreeList; EntityList list = new EntityList(childrenModel); var db = SqlStore.Get(model.SqlStoreOptions.StoreModelId); var dic = new Dictionary <Guid, Entity>(); //TODO: fix pk using var cmd = db.BuildQuery(this); using var conn = db.MakeConnection(); await conn.OpenAsync(); cmd.Connection = conn; Log.Debug(cmd.CommandText); using var reader = await cmd.ExecuteReaderAsync(); while (await reader.ReadAsync()) { Entity obj = FillEntity(model, reader); //设置obj本身的EntitySet成员为已加载,防止从数据库中再次加载 obj.InitEntitySetForLoad(childrenModel); var parentId = obj.GetGuidNullable(parentIdModel.MemberId); if (parentId.HasValue && dic.TryGetValue(parentId.Value, out Entity parent)) { parent.GetEntitySet(childrenModel.MemberId).Add(obj); } else { list.Add(obj); } dic.Add(obj.GetGuid(pk), obj); } return(list); }
internal static void SetDefaultSqlStore(SqlStore defaultSqlStore) { Debug.Assert(defaultSqlStore != null); sqlStores.Add(DefaultSqlStoreId, defaultSqlStore); Default = defaultSqlStore; }