Example #1
0
        public CachedTableMList(ICacheLogicController controller, TableMList table, AliasGenerator aliasGenerator, string lastPartialJoin, string remainingJoins)
            : base(controller)
        {
            this.table = table;

            CachedTableConstructor ctr = this.Constructor = new CachedTableConstructor(this, aliasGenerator);

            //Query
            using (ObjectName.OverrideOptions(new ObjectNameOptions {
                AvoidDatabaseName = true
            }))
            {
                string select = "SELECT\r\n{0}\r\nFROM {1} {2}\r\n".FormatWith(
                    ctr.table.Columns.Values.ToString(c => ctr.currentAlias + "." + c.Name.SqlEscape(), ",\r\n"),
                    table.Name.ToString(),
                    ctr.currentAlias.ToString());

                ctr.remainingJoins = lastPartialJoin + ctr.currentAlias + "." + table.BackReference.Name.SqlEscape() + "\r\n" + remainingJoins;

                query = new SqlPreCommandSimple(select);
            }

            //Reader
            {
                rowReader = ctr.GetRowReader();
            }

            //Completer
            {
                List <Expression> instructions = new List <Expression>
                {
                    Expression.Assign(ctr.origin, Expression.Convert(CachedTableConstructor.originObject, ctr.tupleType)),
                    Expression.Assign(result, ctr.MaterializeField(table.Field))
                };
                var ci = typeof(MList <T> .RowIdElement).GetConstructor(new [] { typeof(T), typeof(PrimaryKey), typeof(int?) });

                var order = table.Order == null?Expression.Constant(null, typeof(int?)) :
                                ctr.GetTupleProperty(table.Order).Nullify();

                instructions.Add(Expression.New(ci, result, CachedTableConstructor.NewPrimaryKey(ctr.GetTupleProperty(table.PrimaryKey)), order));

                var block = Expression.Block(typeof(MList <T> .RowIdElement), new[] { ctr.origin, result }, instructions);

                activatorExpression = Expression.Lambda <Func <object, IRetriever, MList <T> .RowIdElement> >(block, CachedTableConstructor.originObject, CachedTableConstructor.retriever);

                activator = activatorExpression.Compile();

                parentIdGetter = ctr.GetPrimaryKeyGetter(table.BackReference);
                rowIdGetter    = ctr.GetPrimaryKeyGetter(table.PrimaryKey);
            }

            relationalRows = new ResetLazy <Dictionary <PrimaryKey, Dictionary <PrimaryKey, object> > >(() =>
            {
                CacheLogic.AssertSqlDependencyStarted();

                var connector = (SqlConnector)Connector.Current;

                var subConnector = connector.ForDatabase(table.Name.Schema?.Database);

                Dictionary <PrimaryKey, Dictionary <PrimaryKey, object> > result = new Dictionary <PrimaryKey, Dictionary <PrimaryKey, object> >();

                using (MeasureLoad())
                    using (Connector.Override(subConnector))
                        using (Transaction tr = Transaction.ForceNew(IsolationLevel.ReadCommitted))
                        {
                            if (CacheLogic.LogWriter != null)
                            {
                                CacheLogic.LogWriter.WriteLine("Load {0}".FormatWith(GetType().TypeName()));
                            }

                            ((SqlConnector)Connector.Current).ExecuteDataReaderOptionalDependency(query, OnChange, fr =>
                            {
                                object obj          = rowReader(fr);
                                PrimaryKey parentId = parentIdGetter(obj);
                                var dic             = result.TryGetC(parentId);
                                if (dic == null)
                                {
                                    result[parentId] = dic = new Dictionary <PrimaryKey, object>();
                                }

                                dic[rowIdGetter(obj)] = obj;
                            });
                            tr.Commit();
                        }

                return(result);
            }, mode: LazyThreadSafetyMode.ExecutionAndPublication);
        }
Example #2
0
        public CachedTable(ICacheLogicController controller, AliasGenerator aliasGenerator, string lastPartialJoin, string remainingJoins)
            : base(controller)
        {
            this.table = Schema.Current.Table(typeof(T));

            CachedTableConstructor ctr = this.Constructor = new CachedTableConstructor(this, aliasGenerator);

            //Query
            using (ObjectName.OverrideOptions(new ObjectNameOptions {
                AvoidDatabaseName = true
            }))
            {
                string select = "SELECT\r\n{0}\r\nFROM {1} {2}\r\n".FormatWith(
                    Table.Columns.Values.ToString(c => ctr.currentAlias + "." + c.Name.SqlEscape(), ",\r\n"),
                    table.Name.ToString(),
                    ctr.currentAlias.ToString());

                ctr.remainingJoins = lastPartialJoin == null ? null : lastPartialJoin + ctr.currentAlias + ".Id\r\n" + remainingJoins;

                if (ctr.remainingJoins != null)
                {
                    select += ctr.remainingJoins;
                }

                query = new SqlPreCommandSimple(select);
            }


            //Reader
            {
                rowReader = ctr.GetRowReader();
            }

            //Completer
            {
                ParameterExpression me = Expression.Parameter(typeof(T), "me");

                var block = ctr.MaterializeEntity(me, table);

                completerExpression = Expression.Lambda <Action <object, IRetriever, T> >(block, CachedTableConstructor.originObject, CachedTableConstructor.retriever, me);

                completer = completerExpression.Compile();

                idGetter = ctr.GetPrimaryKeyGetter((IColumn)table.PrimaryKey);
            }

            rows = new ResetLazy <Dictionary <PrimaryKey, object> >(() =>
            {
                CacheLogic.AssertSqlDependencyStarted();

                var connector = (SqlConnector)Connector.Current;
                Table table   = connector.Schema.Table(typeof(T));

                var subConnector = connector.ForDatabase(table.Name.Schema?.Database);

                Dictionary <PrimaryKey, object> result = new Dictionary <PrimaryKey, object>();
                using (MeasureLoad())
                    using (Connector.Override(subConnector))
                        using (Transaction tr = Transaction.ForceNew(IsolationLevel.ReadCommitted))
                        {
                            if (CacheLogic.LogWriter != null)
                            {
                                CacheLogic.LogWriter.WriteLine("Load {0}".FormatWith(GetType().TypeName()));
                            }

                            ((SqlConnector)Connector.Current).ExecuteDataReaderOptionalDependency(query, OnChange, fr =>
                            {
                                object obj            = rowReader(fr);
                                result[idGetter(obj)] = obj; //Could be repeated joins
                            });
                            tr.Commit();
                        }

                return(result);
            }, mode: LazyThreadSafetyMode.ExecutionAndPublication);

            if (!CacheLogic.WithSqlDependency && lastPartialJoin.HasText()) //Is semi
            {
                semiCachedController = new SemiCachedController <T>(this);
            }
        }