Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        /// <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));
        }
Esempio n. 3
0
 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);
     }
 }
Esempio n. 4
0
        /// <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);
        }
Esempio n. 5
0
        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
            }
        }
Esempio n. 6
0
        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));
        }
Esempio n. 7
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);
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        /// <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);
        }
Esempio n. 10
0
 internal static void SetDefaultSqlStore(SqlStore defaultSqlStore)
 {
     Debug.Assert(defaultSqlStore != null);
     sqlStores.Add(DefaultSqlStoreId, defaultSqlStore);
     Default = defaultSqlStore;
 }