Example #1
0
        /// <summary>
        /// Constructs a DbDataJoiner instance
        /// </summary>
        /// <param name="joinOn">Property path from the root object down to the lookup key</param>
        /// <param name="dimTableTarget">Table information of the remote dimension table</param>
        /// <param name="option">Option to use for this dataflow</param>
        /// <param name="batchSize">The batch size for a batched remote look up</param>
        /// <param name="cacheSize">The local cache item count (part of the remote table)</param>
        public DbDataJoiner(Expression <Func <TIn, TLookupKey> > joinOn, TargetTable dimTableTarget, DataflowOptions option, int batchSize = 8 * 1024, int cacheSize = 1024 * 1024)
            : base(option)
        {
            m_dimTableTarget  = dimTableTarget;
            m_batchSize       = batchSize;
            m_batcher         = new BatchBlock <TIn>(batchSize, option.ToGroupingBlockOption()).ToDataflow(option);
            m_batcher.Name    = "Batcher";
            m_lookupNode      = new TransformManyDataflow <JoinBatch <TIn>, TIn>(this.JoinBatch, option);
            m_lookupNode.Name = "LookupNode";
            m_typeAccessor    = TypeAccessorManager <TIn> .GetAccessorForTable(dimTableTarget);

            m_keyComparer = typeof(TLookupKey) == typeof(byte[])
                                    ? (IEqualityComparer <TLookupKey>)((object)new ByteArrayEqualityComparer())
                                    : EqualityComparer <TLookupKey> .Default;
            m_rowCache = new RowCache <TLookupKey>(cacheSize, m_keyComparer);
            m_logger   = Utils.GetNamespaceLogger();

            m_joinOnMapping = m_typeAccessor.DbColumnMappings.First(m => m.Host.PropertyInfo == this.ExtractPropertyInfo(joinOn));

            var transformer =
                new TransformBlock <TIn[], JoinBatch <TIn> >(
                    array => new JoinBatch <TIn>(array, CacheLookupStrategy.RemoteLookup), option.ToExecutionBlockOption()).ToDataflow(option);

            transformer.Name = "ArrayToJoinBatchConverter";

            m_batcher.LinkTo(transformer);
            transformer.LinkTo(m_lookupNode);

            RegisterChild(m_batcher);
            RegisterChild(transformer);
            RegisterChild(m_lookupNode);

            m_dimInserter = new DimTableInserter(this, dimTableTarget, joinOn, option)
            {
                Name = "DimInserter"
            };
            var hb = new HeartbeatNode <JoinBatch <TIn> >(option);

            m_dimInserter.RegisterDependency(m_lookupNode);

            m_dimInserter.LinkTo(hb);
            hb.LinkTo(m_lookupNode);

            RegisterChild(m_dimInserter);
            RegisterChild(hb);
            RegisterChildRing(transformer.CompletionTask, m_lookupNode, m_dimInserter, hb);
        }
Example #2
0
        /// <summary>
        /// Override this method to customize row cache initialization logic
        /// </summary>
        protected virtual void InitializeCache(RowCache <TLookupKey> cache)
        {
            string selectPartial = string.Format(
                "select TOP {3} [{0}], [{1}] from {2} order by [{0}] desc",
                Utils.GetAutoIncrementColumn(m_typeAccessor.SchemaTable.Columns).ColumnName,
                m_joinOnMapping.DestColumnName,
                m_dimTableTarget.TableName,
                cache.SizeLimit);

            m_logger.DebugFormat("[{0}] Start to initialize cache using sql: {1}", FullName, selectPartial);

            using (var connection = new SqlConnection(m_dimTableTarget.ConnectionString))
            {
                connection.Open();

                SqlCommand command = new SqlCommand(selectPartial, connection);

                var  autoKeyColumn  = Utils.GetAutoIncrementColumn(m_typeAccessor.SchemaTable.Columns);
                bool is64BitAutoKey = autoKeyColumn.DataType == typeof(long);

                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    long       dimKey          = is64BitAutoKey ? reader.GetInt64(0) : reader.GetInt32(0); //$inserted.AutoKey
                    TLookupKey joinColumnValue = (TLookupKey)reader[1];                                    //$inserted.JoinOnColumn

                    //add to the subcache no matter it is an "UPDATE" or "INSERT"
                    cache.TryAdd(
                        joinColumnValue,
                        new PartialDimRow <TLookupKey> {
                        AutoIncrementKey = dimKey, JoinOn = joinColumnValue
                    });
                }
            }

            m_logger.DebugFormat("[{0}] Global cache initialized with {1} items", FullName, cache.Count);
        }