Example #1
0
        /// <summary>
        /// Returns the Key Count of an Extract.
        /// </summary>
        /// <param name="AExtractId">ExtractId of the Extract that the KeyCount should
        /// get returned for.</param>
        /// <returns>The Key Count of the Extract, or -1 if the Extract with the given
        /// Extract Id doesn't exist.</returns>
        public static Int32 GetExtractKeyCount(int AExtractId)
        {
            Boolean NewTransaction;

            TDBTransaction ReadTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted,
                                                                                               TEnforceIsolationLevel.eilMinimum,
                                                                                               out NewTransaction);

            try
            {
                MExtractMasterTable ExtractDT = MExtractMasterAccess.LoadByPrimaryKey(AExtractId, ReadTransaction);

                if (ExtractDT.Rows.Count == 1)
                {
                    return(ExtractDT[0].KeyCount);
                }
                else
                {
                    return(-1);
                }
            }
            finally
            {
                if (NewTransaction)
                {
                    DBAccess.GDBAccessObj.CommitTransaction();
                    TLogging.LogAtLevel(8, "TExtractsHandling.GetExtractKeyCount: committed own transaction.");
                }
            }
        }
Example #2
0
        /// <summary>
        /// Updates the KeyCount on an Extract.
        /// </summary>
        /// <param name="AExtractId">ExtractId of the Extract that the KeyCount should
        /// get updated for.</param>
        /// <param name="ACount">New Key Count.</param>
        /// <param name="AVerificationResult">Contains errors or DB call exceptions, if there are any.</param>
        /// <returns>True if the updating was successful, otherwise false.</returns>
        public static bool UpdateExtractKeyCount(int AExtractId, int ACount,
                                                 out TVerificationResultCollection AVerificationResult)
        {
            TDBTransaction Transaction  = null;
            bool           SubmissionOK = false;
            TVerificationResultCollection VerificationResult = new TVerificationResultCollection();

            DBAccess.GDBAccessObj.GetNewOrExistingAutoTransaction(IsolationLevel.Serializable, ref Transaction, ref SubmissionOK,
                                                                  delegate
            {
                MExtractMasterTable ExtractMasterDT = MExtractMasterAccess.LoadByPrimaryKey(AExtractId,
                                                                                            Transaction);

                if (ExtractMasterDT.Rows.Count == 1)
                {
                    ExtractMasterDT[0].KeyCount = ACount;

                    MExtractMasterAccess.SubmitChanges(ExtractMasterDT, Transaction);
                    SubmissionOK = true;
                }
                else
                {
                    VerificationResult.Add(new TVerificationResult(
                                               "TExtractsHandling.UpdateExtractCount", "Extract with Extract Id " + AExtractId.ToString() +
                                               " doesn't exist!", TResultSeverity.Resv_Critical));
                }
            });

            AVerificationResult = VerificationResult;

            return(SubmissionOK);
        }
Example #3
0
        /// <summary>
        /// Deletes an Extract.
        /// </summary>
        /// <param name="AExtractId">ExtractId of the Extract that should get
        /// deleted.</param>
        /// <param name="AExtractNotDeletable">True if the Deletable Flag of the
        /// Extract if false.</param>
        /// <param name="AVerificationResult">Nil if all verifications are OK,
        /// otherwise filled with a TVerificationResult object.</param>
        /// <returns>True if the Extract was deleted, otherwise false.</returns>
        public static bool DeleteExtract(int AExtractId,
                                         out bool AExtractNotDeletable,
                                         out TVerificationResult AVerificationResult)
        {
            TDBTransaction      Transaction  = null;
            bool                SubmissionOK = false;
            MExtractMasterTable ExtractMasterDT;
            Boolean             ExtractNotDeletable = false;
            TVerificationResult VerificationResult  = null;

            DBAccess.GDBAccessObj.GetNewOrExistingAutoTransaction(IsolationLevel.Serializable, ref Transaction, ref SubmissionOK,
                                                                  delegate
            {
                ExtractMasterDT = MExtractMasterAccess.LoadByPrimaryKey(AExtractId,
                                                                        Transaction);

                if (ExtractMasterDT.Rows.Count == 1)
                {
                    if (ExtractMasterDT[0].Deletable)
                    {
                        MExtractMasterCascading.DeleteByPrimaryKey(AExtractId,
                                                                   Transaction, true);
                        SubmissionOK = true;
                    }
                    else
                    {
                        ExtractNotDeletable = true;
                        SubmissionOK        = false;
                    }
                }
                else
                {
                    VerificationResult = new TVerificationResult(
                        "TExtractsHandling.DeleteExtract", "Extract with Extract Id " + AExtractId.ToString() +
                        "doesn't exist!", TResultSeverity.Resv_Critical);
                    SubmissionOK = false;
                }
            });

            AVerificationResult  = VerificationResult;
            AExtractNotDeletable = ExtractNotDeletable;

            return(SubmissionOK);
        }
Example #4
0
        /// <summary>
        /// Returns the Key Count of an Extract.
        /// </summary>
        /// <param name="AExtractId">ExtractId of the Extract that the KeyCount should
        /// get returned for.</param>
        /// <returns>The Key Count of the Extract, or -1 if the Extract with the given
        /// Extract Id doesn't exist.</returns>
        public static Int32 GetExtractKeyCount(int AExtractId)
        {
            TDBTransaction Transaction = new TDBTransaction();
            Int32          KeyCount    = 0;

            DBAccess.ReadTransaction(
                ref Transaction,
                delegate
            {
                MExtractMasterTable ExtractDT = MExtractMasterAccess.LoadByPrimaryKey(AExtractId, Transaction);

                if (ExtractDT.Rows.Count == 1)
                {
                    KeyCount = ExtractDT[0].KeyCount;
                }
                else
                {
                    KeyCount = -1;
                }
            });

            return(KeyCount);
        }
Example #5
0
        /// <summary>
        /// Returns the Key Count of an Extract.
        /// </summary>
        /// <param name="AExtractId">ExtractId of the Extract that the KeyCount should
        /// get returned for.</param>
        /// <returns>The Key Count of the Extract, or -1 if the Extract with the given
        /// Extract Id doesn't exist.</returns>
        public static Int32 GetExtractKeyCount(int AExtractId)
        {
            TDBTransaction Transaction = null;
            Int32          KeyCount    = 0;

            DBAccess.GDBAccessObj.GetNewOrExistingAutoReadTransaction(IsolationLevel.ReadCommitted,
                                                                      TEnforceIsolationLevel.eilMinimum,
                                                                      ref Transaction,
                                                                      delegate
            {
                MExtractMasterTable ExtractDT = MExtractMasterAccess.LoadByPrimaryKey(AExtractId, Transaction);

                if (ExtractDT.Rows.Count == 1)
                {
                    KeyCount = ExtractDT[0].KeyCount;
                }
                else
                {
                    KeyCount = -1;
                }
            });

            return(KeyCount);
        }
Example #6
0
        /// <summary>
        /// extend an extract from a list of best addresses
        /// </summary>
        /// <param name="AExtractId">Extract Id of the Extract to extend</param>
        /// <param name="APartnerKeysTable"></param>
        /// <param name="APartnerKeyColumn">number of the column that contains the partner keys</param>
        /// <param name="ASiteKeyColumn">number of the column that contains the site keys</param>
        /// <param name="ALocationKeyColumn">number of the column that contains the location keys</param>
        /// <param name="AKeyCount">The number of keys that were actually added to the extract (any duplicates are excluded)</param>
        /// <param name="AIgnoredKeyList">A reference to a List of long.  If not null the server will fill it with the partner keys that were ignored.  Does not include duplicates.</param>
        /// <param name="AIgnoreDuplicates">true if duplicates should be looked out for. Can be set to false if called only once and not several times per extract.</param>
        /// <param name="AIgnoreInactive">true if inactive partners should be ignored</param>
        /// <param name="AIgnoreNonMailingLocations">true to ignore if the partner's best address is a non-mailing location</param>
        /// <param name="AIgnoreNoSolicitations">true to ignore partners where the No Solicitations flag is set</param>
        public static void ExtendExtractFromListOfPartnerKeys(
            Int32 AExtractId,
            DataTable APartnerKeysTable,
            Int32 APartnerKeyColumn,
            Int32 ASiteKeyColumn,
            Int32 ALocationKeyColumn,
            out Int32 AKeyCount,
            out List <long> AIgnoredKeyList,
            bool AIgnoreDuplicates,
            bool AIgnoreInactive,
            bool AIgnoreNonMailingLocations,
            bool AIgnoreNoSolicitations)
        {
            int RecordCounter = 0;
            PPartnerLocationTable PartnerLocationKeysTable;
            Int64 PartnerKey;

            List <long> ignoredKeyList = new List <long>();

            TDBTransaction Transaction  = null;
            bool           SubmissionOK = true;

            DBAccess.GDBAccessObj.GetNewOrExistingAutoTransaction(IsolationLevel.Serializable, ref Transaction, ref SubmissionOK,
                                                                  delegate
            {
                // Pre-process the table to remove partner rows that do not match the filter requirements
                for (int i = APartnerKeysTable.Rows.Count - 1; i >= 0; i--)
                {
                    DataRow dr       = APartnerKeysTable.Rows[i];
                    Int64 partnerKey = Convert.ToInt64(dr[APartnerKeyColumn]);

                    // Get a partner record containing our fields of interest
                    StringCollection fields = new StringCollection();
                    fields.Add(PPartnerTable.GetStatusCodeDBName());
                    fields.Add(PPartnerTable.GetNoSolicitationsDBName());
                    DataTable dt = PPartnerAccess.LoadByPrimaryKey(partnerKey, fields, Transaction);

                    if (dt.Rows.Count > 0)
                    {
                        if (AIgnoreInactive || AIgnoreNoSolicitations)
                        {
                            bool isActive         = false;
                            bool isNoSolicitation = false;
                            object o = dt.Rows[0][PPartnerTable.GetStatusCodeDBName()];

                            if (o != null)
                            {
                                TStdPartnerStatusCode statusCode = SharedTypes.StdPartnerStatusCodeStringToEnum(o.ToString());
                                isActive = (statusCode == TStdPartnerStatusCode.spscACTIVE);
                            }

                            o = dt.Rows[0][PPartnerTable.GetNoSolicitationsDBName()];

                            if (o != null)
                            {
                                isNoSolicitation = Convert.ToBoolean(o);
                            }

                            if ((AIgnoreInactive && !isActive) || (AIgnoreNoSolicitations && isNoSolicitation))
                            {
                                ignoredKeyList.Add(partnerKey);
                                APartnerKeysTable.Rows.Remove(dr);
                            }
                        }
                    }
                    else
                    {
                        ignoredKeyList.Add(partnerKey);
                    }
                }

                MExtractTable ExtractTable = new MExtractTable();
                ExtractTable = MExtractAccess.LoadViaMExtractMaster(AExtractId, Transaction);

                // Location Keys need to be determined as extracts do not only need partner keys but
                // also Location Keys.
                DetermineBestLocationKeys(APartnerKeysTable, APartnerKeyColumn, ASiteKeyColumn,
                                          ALocationKeyColumn, out PartnerLocationKeysTable,
                                          Transaction);

                // use the returned table which contains partner and location keys to build the extract
                foreach (PPartnerLocationRow PartnerLocationRow in PartnerLocationKeysTable.Rows)
                {
                    PartnerKey = PartnerLocationRow.PartnerKey;

                    if (PartnerKey > 0)
                    {
                        if (AIgnoreNonMailingLocations)
                        {
                            // The PartnerLocationRow only contains the PK fields so now we need to get the SendMail column
                            StringCollection fields = new StringCollection();
                            fields.Add(PPartnerLocationTable.GetSendMailDBName());

                            PPartnerLocationTable t =
                                PPartnerLocationAccess.LoadByPrimaryKey(PartnerKey, PartnerLocationRow.SiteKey,
                                                                        PartnerLocationRow.LocationKey, fields, Transaction);

                            if ((t != null) && (t.Rows.Count > 0) && (((PPartnerLocationRow)t.Rows[0]).SendMail == false))
                            {
                                ignoredKeyList.Add(PartnerKey);
                                continue;
                            }
                        }

                        RecordCounter += 1;
                        TLogging.LogAtLevel(1, "Preparing Partner " + PartnerKey + " (Record Number " + RecordCounter + ")");

                        // add row for partner to extract and fill with contents
                        MExtractRow NewRow = ExtractTable.NewRowTyped();
                        NewRow.ExtractId   = AExtractId;
                        NewRow.PartnerKey  = PartnerKey;
                        NewRow.SiteKey     = Convert.ToInt64(PartnerLocationRow[PPartnerLocationTable.GetSiteKeyDBName()]);
                        NewRow.LocationKey = Convert.ToInt32(PartnerLocationRow[PPartnerLocationTable.GetLocationKeyDBName()]);

                        // only add row if it does not already exist for this partner
                        if (AIgnoreDuplicates || !ExtractTable.Rows.Contains(new object[] { NewRow.ExtractId, NewRow.PartnerKey, NewRow.SiteKey }))
                        {
                            ExtractTable.Rows.Add(NewRow);
                        }
                    }
                }

                if (ExtractTable.Rows.Count > 0)
                {
                    // update field in extract master for quick access to number of partners in extract
                    MExtractMasterTable ExtractMaster = MExtractMasterAccess.LoadByPrimaryKey(AExtractId, Transaction);
                    ExtractMaster[0].KeyCount         = ExtractTable.Rows.Count;

                    ExtractTable.ThrowAwayAfterSubmitChanges = true;     // no need to keep data as this increases speed significantly

                    MExtractAccess.SubmitChanges(ExtractTable, Transaction);

                    MExtractMasterAccess.SubmitChanges(ExtractMaster, Transaction);
                }
            });

            AKeyCount       = RecordCounter;
            AIgnoredKeyList = ignoredKeyList;
        }
Example #7
0
        /// <summary>
        /// extend an extract from a list of best addresses
        /// </summary>
        /// <param name="AExtractId">Extract Id of the Extract to extend</param>
        /// <param name="APartnerKeysTable"></param>
        /// <param name="APartnerKeyColumn">number of the column that contains the partner keys</param>
        /// <param name="ASiteKeyColumn">number of the column that contains the site keys</param>
        /// <param name="ALocationKeyColumn">number of the column that contains the location keys</param>
        /// <param name="AIgnoreDuplicates">true if duplicates should be looked out for. Can be set to false if called only once and not several times per extract.</param>
        /// <param name="ACommitTransaction">true if transaction should be committed at end of method</param>
        public static void ExtendExtractFromListOfPartnerKeys(
            Int32 AExtractId,
            DataTable APartnerKeysTable,
            Int32 APartnerKeyColumn,
            Int32 ASiteKeyColumn,
            Int32 ALocationKeyColumn,
            bool AIgnoreDuplicates,
            bool ACommitTransaction)
        {
            Boolean NewTransaction;
            int     RecordCounter = 0;
            PPartnerLocationTable PartnerLocationKeysTable;
            Int64 PartnerKey;

            TDBTransaction WriteTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.Serializable,
                                                                                                TEnforceIsolationLevel.eilMinimum, out NewTransaction);

            try
            {
                MExtractTable ExtractTable = new MExtractTable();
                ExtractTable = MExtractAccess.LoadViaMExtractMaster(AExtractId, WriteTransaction);

                // Location Keys need to be determined as extracts do not only need partner keys but
                // also Location Keys.
                DetermineBestLocationKeys(APartnerKeysTable, APartnerKeyColumn, ASiteKeyColumn,
                                          ALocationKeyColumn, out PartnerLocationKeysTable,
                                          WriteTransaction);

                // use the returned table which contains partner and location keys to build the extract
                foreach (PPartnerLocationRow PartnerLocationRow in PartnerLocationKeysTable.Rows)
                {
                    PartnerKey = Convert.ToInt64(PartnerLocationRow[PPartnerLocationTable.GetPartnerKeyDBName()]);

                    if (PartnerKey > 0)
                    {
                        RecordCounter += 1;
                        TLogging.Log("Preparing Partner " + PartnerKey.ToString() + " (Record Number " + RecordCounter.ToString() + ")");

                        // add row for partner to extract and fill with contents
                        MExtractRow NewRow = ExtractTable.NewRowTyped();
                        NewRow.ExtractId   = AExtractId;
                        NewRow.PartnerKey  = PartnerKey;
                        NewRow.SiteKey     = Convert.ToInt64(PartnerLocationRow[PPartnerLocationTable.GetSiteKeyDBName()]);
                        NewRow.LocationKey = Convert.ToInt32(PartnerLocationRow[PPartnerLocationTable.GetLocationKeyDBName()]);

                        // only add row if it does not already exist for this partner
                        if (AIgnoreDuplicates || !ExtractTable.Rows.Contains(new object[] { NewRow.ExtractId, NewRow.PartnerKey, NewRow.SiteKey }))
                        {
                            ExtractTable.Rows.Add(NewRow);
                        }
                    }
                }

                if (ExtractTable.Rows.Count > 0)
                {
                    // update field in extract master for quick access to number of partners in extract
                    MExtractMasterTable ExtractMaster = MExtractMasterAccess.LoadByPrimaryKey(AExtractId, WriteTransaction);
                    ExtractMaster[0].KeyCount = ExtractTable.Rows.Count;

                    ExtractTable.ThrowAwayAfterSubmitChanges = true; // no need to keep data as this increases speed significantly

                    MExtractAccess.SubmitChanges(ExtractTable, WriteTransaction);

                    MExtractMasterAccess.SubmitChanges(ExtractMaster, WriteTransaction);
                }

                if (ACommitTransaction)
                {
                    DBAccess.GDBAccessObj.CommitTransaction();
                }
            }
            catch (Exception Exc)
            {
                TLogging.Log("An Exception occured while extending an Extract from a list of Partner Keys:" + Environment.NewLine + Exc.ToString());

                if (NewTransaction)
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                }

                throw;
            }
        }
Example #8
0
        /// <summary>
        /// Updates the KeyCount on an Extract.
        /// </summary>
        /// <param name="AExtractId">ExtractId of the Extract that the KeyCount should
        /// get updated for.</param>
        /// <param name="ACount">New Key Count.</param>
        /// <param name="AVerificationResult">Contains errors or DB call exceptions, if there are any.</param>
        /// <returns>True if the updating was successful, otherwise false.</returns>
        public static bool UpdateExtractKeyCount(int AExtractId, int ACount,
                                                 out TVerificationResultCollection AVerificationResult)
        {
            Boolean NewTransaction;
            Boolean Success = true;

            AVerificationResult = null;

            TDBTransaction WriteTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(
                IsolationLevel.Serializable, TEnforceIsolationLevel.eilMinimum, out NewTransaction);

            try
            {
                MExtractMasterTable ExtractMasterDT = MExtractMasterAccess.LoadByPrimaryKey(AExtractId,
                                                                                            WriteTransaction);

                if (ExtractMasterDT.Rows.Count == 1)
                {
                    ExtractMasterDT[0].KeyCount = ACount;

                    MExtractMasterAccess.SubmitChanges(ExtractMasterDT, WriteTransaction);
                }
                else
                {
                    AVerificationResult.Add(new TVerificationResult(
                                                "TExtractsHandling.UpdateExtractCount", "Extract with Extract Id " + AExtractId.ToString() +
                                                " doesn't exist!", TResultSeverity.Resv_Critical));

                    Success = false;
                }

                if (Success)
                {
                    if (NewTransaction)
                    {
                        DBAccess.GDBAccessObj.CommitTransaction();

                        TLogging.LogAtLevel(8, "TExtractsHandling.UpdateExtractCount: committed own transaction!");
                    }
                }
                else
                {
                    if (NewTransaction)
                    {
                        DBAccess.GDBAccessObj.RollbackTransaction();

                        TLogging.LogAtLevel(8, "TExtractsHandling.UpdateExtractCount: ROLLED BACK own transaction!");
                    }
                }
            }
            catch (Exception Exc)
            {
                TLogging.Log("An Exception occured during the updating of an Extracts' Key Count:" + Environment.NewLine + Exc.ToString());

                if (NewTransaction)
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                }

                throw;
            }

            return(Success);
        }
Example #9
0
        /// <summary>
        /// Deletes an Extract.
        /// </summary>
        /// <param name="AExtractId">ExtractId of the Extract that should get
        /// deleted.</param>
        /// <param name="AExtractNotDeletable">True if the Deletable Flag of the
        /// Extract if false.</param>
        /// <param name="AVerificationResult">Nil if all verifications are OK,
        /// otherwise filled with a TVerificationResult object.</param>
        /// <returns>True if the Extract was deleted, otherwise false.</returns>
        public static bool DeleteExtract(int AExtractId,
                                         out bool AExtractNotDeletable,
                                         out TVerificationResult AVerificationResult)
        {
            TDBTransaction      WriteTransaction;
            MExtractMasterTable ExtractMasterDT;
            Boolean             NewTransaction;
            Boolean             Success = false;

            AVerificationResult  = null;
            AExtractNotDeletable = false;

            WriteTransaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(
                IsolationLevel.Serializable,
                TEnforceIsolationLevel.eilMinimum,
                out NewTransaction);

            try
            {
                ExtractMasterDT = MExtractMasterAccess.LoadByPrimaryKey(AExtractId,
                                                                        WriteTransaction);

                if (ExtractMasterDT.Rows.Count == 1)
                {
                    if (ExtractMasterDT[0].Deletable)
                    {
                        MExtractMasterCascading.DeleteByPrimaryKey(AExtractId,
                                                                   WriteTransaction, true);
                        Success = true;
                    }
                    else
                    {
                        AExtractNotDeletable = true;
                        Success = false;
                    }
                }
                else
                {
                    AVerificationResult = new TVerificationResult(
                        "TExtractsHandling.DeleteExtract", "Extract with Extract Id " + AExtractId.ToString() +
                        "doesn't exist!", TResultSeverity.Resv_Critical);
                    Success = false;
                }
            }
            catch (Exception Exp)
            {
                TLogging.LogAtLevel(8, "TExtractsHandling.DeleteExtract: Exception occured: " + Exp.ToString());
                throw;
            }
            finally
            {
                if (Success)
                {
                    if (NewTransaction)
                    {
                        DBAccess.GDBAccessObj.CommitTransaction();
                        TLogging.LogAtLevel(8, "TExtractsHandling.DeleteExtract: committed own transaction!");
                    }
                }
                else
                {
                    if (NewTransaction)
                    {
                        DBAccess.GDBAccessObj.RollbackTransaction();
                        TLogging.LogAtLevel(8, "TExtractsHandling.DeleteExtract: ROLLED BACK own transaction!");
                    }
                }
            }

            return(Success);
        }
Example #10
0
        /// <summary>
        /// extend an extract from a list of best addresses
        /// </summary>
        /// <param name="AExtractId">Extract Id of the Extract to extend</param>
        /// <param name="APartnerKeysTable"></param>
        /// <param name="APartnerKeyColumn">number of the column that contains the partner keys</param>
        /// <param name="ASiteKeyColumn">number of the column that contains the site keys</param>
        /// <param name="ALocationKeyColumn">number of the column that contains the location keys</param>
        /// <param name="AIgnoreDuplicates">true if duplicates should be looked out for. Can be set to false if called only once and not several times per extract.</param>
        public static void ExtendExtractFromListOfPartnerKeys(
            Int32 AExtractId,
            DataTable APartnerKeysTable,
            Int32 APartnerKeyColumn,
            Int32 ASiteKeyColumn,
            Int32 ALocationKeyColumn,
            bool AIgnoreDuplicates)
        {
            int RecordCounter = 0;
            PPartnerLocationTable PartnerLocationKeysTable;
            Int64 PartnerKey;

            TDBTransaction Transaction  = null;
            bool           SubmissionOK = true;

            DBAccess.GDBAccessObj.GetNewOrExistingAutoTransaction(IsolationLevel.Serializable, ref Transaction, ref SubmissionOK,
                                                                  delegate
            {
                MExtractTable ExtractTable = new MExtractTable();
                ExtractTable = MExtractAccess.LoadViaMExtractMaster(AExtractId, Transaction);

                // Location Keys need to be determined as extracts do not only need partner keys but
                // also Location Keys.
                DetermineBestLocationKeys(APartnerKeysTable, APartnerKeyColumn, ASiteKeyColumn,
                                          ALocationKeyColumn, out PartnerLocationKeysTable,
                                          Transaction);

                // use the returned table which contains partner and location keys to build the extract
                foreach (PPartnerLocationRow PartnerLocationRow in PartnerLocationKeysTable.Rows)
                {
                    PartnerKey = Convert.ToInt64(PartnerLocationRow[PPartnerLocationTable.GetPartnerKeyDBName()]);

                    if (PartnerKey > 0)
                    {
                        RecordCounter += 1;
                        TLogging.LogAtLevel(1, "Preparing Partner " + PartnerKey + " (Record Number " + RecordCounter + ")");

                        // add row for partner to extract and fill with contents
                        MExtractRow NewRow = ExtractTable.NewRowTyped();
                        NewRow.ExtractId   = AExtractId;
                        NewRow.PartnerKey  = PartnerKey;
                        NewRow.SiteKey     = Convert.ToInt64(PartnerLocationRow[PPartnerLocationTable.GetSiteKeyDBName()]);
                        NewRow.LocationKey = Convert.ToInt32(PartnerLocationRow[PPartnerLocationTable.GetLocationKeyDBName()]);

                        // only add row if it does not already exist for this partner
                        if (AIgnoreDuplicates || !ExtractTable.Rows.Contains(new object[] { NewRow.ExtractId, NewRow.PartnerKey, NewRow.SiteKey }))
                        {
                            ExtractTable.Rows.Add(NewRow);
                        }
                    }
                }

                if (ExtractTable.Rows.Count > 0)
                {
                    // update field in extract master for quick access to number of partners in extract
                    MExtractMasterTable ExtractMaster = MExtractMasterAccess.LoadByPrimaryKey(AExtractId, Transaction);
                    ExtractMaster[0].KeyCount         = ExtractTable.Rows.Count;

                    ExtractTable.ThrowAwayAfterSubmitChanges = true;     // no need to keep data as this increases speed significantly

                    MExtractAccess.SubmitChanges(ExtractTable, Transaction);

                    MExtractMasterAccess.SubmitChanges(ExtractMaster, Transaction);
                }
            });
        }