Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 748925
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 14, 20262026-05-14T14:22:34+00:00 2026-05-14T14:22:34+00:00

I have 2 databases – (1) Feeds, (2) Production. The feeds database is fed

  • 0

I have 2 databases – (1) Feeds, (2) Production. The feeds database is fed from client files that we get on a daily basis and is, from my viewpoint, a read only source of data. When a feed file is received the feed app does its thing then finally calls a web service on the production site. This web service then does a sync between the feeds DB and the Prod DB. In essence this is the pseudo code:

  • Get all Feed items for a client
  • Get all prod items for the same client
  • Using LINQ for Objects, get (1) All items that cause an UPDATE, (2) All items that cause a DELETE and (3) All items that cause an INSERT.
  • Process UPDATES
  • Process DELETES
  • Process INSERTS

For the core piece of code that separates INSERTS, UPDATES and DELETES:

List<model.AutoWithImage> feedProductList = _dbFeed.AutoWithImage.Where(feedProduct => feedProduct.ClientID == ClientID).ToList();
List<model.vwCompanyDetails> companyDetailList = _dbRiv.vwCompanyDetails.Where(feedProduct => feedProduct.ClientID == ClientID).ToList();
foreach (model.vwCompanyDetails companyDetail in companyDetailList)
{
    List<model.Product> rivProductList = _dbRiv.Product.Include("Company").Where(feedProduct => feedProduct.Company.CompanyId == companyDetail.CompanyId).ToList();

    foreach (model.AutoWithImage feedProduct in feedProductList)
    {
        bool alreadyExists = false;
        model.Company company = null;
        foreach (model.Product rivProduct in rivProductList)
        {
            if (feedProduct.StockNumber == rivProduct.SKU)
            {
                alreadyExists = true;

                // Active feed items...
                if (feedProduct.Active)
                {
                    // Changed since last sync...
                    if (feedProduct.Updated > rivProduct.LastFeedUpdate)
                    {
                        model.Product updateProduct = new model.Product();
                        updateProduct.ProductId = rivProduct.ProductId;
                        // removed for brevity
                        updateProductList.Add(updateProduct);
                    }
                    // Not changed since last sync...
                    else if (feedProduct.Updated <= rivProduct.LastFeedUpdate)
                    {
                        //nop
                    }
                }
                // No longer active feed products...
                else if (!feedProduct.Active)
                {
                    model.Product deleteProduct = new model.Product();
                    deleteProduct = rivProduct;
                    // removed for brevity
                    deleteProductList.Add(deleteProduct);
                }
            }

            if (company == null)
                company = rivProduct.Company;
        }

        // Found feedProduct new product...
        if (!alreadyExists)
        {
            model.Product insertProduct = new Product();
            insertProduct.ProductId = Guid.NewGuid();
            // removed for brevity
            insertProductList.Add(insertProduct);
        }
    }
}

Yes, I know there are more efficient ways of doing this and I am starting to use them. However, the code above works, relatively fast and breaks my data into 3 List<> sets.

My question is more on handling the _dbRiv.SaveChanges() method. When I issue it it appears to fire off all 3 sets (above). I am trying to track down a unique key violation and with this in a batch I am not finding the one or two records that are guilty of violating the constraint. I am sure I missed something somewhere in my thinking of how LINQ for SQL really works.

What I’d like to do is:

  • Execute a Save on just the UPDATES.
    Do some other stuff then,
  • Execute a Save on just the DELETES.
    Do some other stuff then,
  • Execute a Save, one by one (for now)
    on the INSERTS.

Is there some way to issue a SaveChanges on one batch at a time?
Is there a way to foreach the InsertProductList object and do a SaveChanges one row at a time?
Am I barking up the wrong tree?


EDIT:
While I know I can call a stored proc from EF, my intention is to learn how to convert a stored proc to EF.

I wrote what I want in SQL and here it is (and this works exactly how we need it to):

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER PROC [dbo].[ExecuteSync] @ClientID AS BIGINT AS
BEGIN
    DECLARE @cid UNIQUEIDENTIFIER

    DECLARE c1 CURSOR FOR
    SELECT CompanyID FROM CompanyDetails WHERE ClientID = @ClientID
    OPEN c1
    FETCH NEXT FROM c1 INTO @cid
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET NOCOUNT ON
        SELECT 'Syncing feed data for ' + CompanyName FROM Company WHERE CompanyId = @cid
        SET NOCOUNT OFF
        -- n/a --------------------------------------------------------------------------------------------------------------------------------------------------------------------
        --SELECT a.*
        --     , p.*
        --  FROM RIVFeeds..AutoWithImage a
        -- INNER JOIN Product p ON a.StockNumber = p.SKU
        -- WHERE ClientID = @ClientID
        --   AND a.Active = 1
        --   AND a.Updated <= p.LastFeedUpdate

        -- Needs UPDATE -----------------------------------------------------------------------------------------------------------------------------------------------------------
        PRINT '--[ UPDATE ]--'
        UPDATE Product
           SET [Description] = ''
             , [Image] = a.ImageURL
             , isDeleted = a.Active ^ 1
             , isFromFeed = 1
             , LastFeedUpdate = a.Updated
             , LowestPrice = a.GuaranteedSalePrice
             , RetailPrice = a.ListPrice
             , [Title] = ''
             , Updated = GETUTCDATE()
             , UpdatedBy = 'Feed Sync Process'
          FROM RIVFeeds..AutoWithImage a
         INNER JOIN Product p ON a.StockNumber = p.SKU AND a.AutoID = p.alternateProductID
         WHERE ClientID = @ClientID
           AND p.CompanyID = @cid
           AND a.Updated > p.LastFeedUpdate

        -- Needs BACKUP -----------------------------------------------------------------------------------------------------------------------------------------------------------
        PRINT '--[ BACKUP #1 ]--'
        INSERT INTO ProductDeleted(ProductId, alternateProductID, CompanyID, CharacterId, URLDomain, SKU, Title, Description, ButtonConfig, RetailPrice, LowestPrice, Image
                  , BackgroundColor, FontColor, buttonPositionCSS, isFromFeed, isDeleted, LastFeedUpdate, Created, CreatedBy, Updated, UpdatedBy)
        SELECT p.ProductId, p.alternateProductID, p.CompanyID, p.CharacterId, p.URLDomain, p.SKU, p.Title, p.Description, p.ButtonConfig, p.RetailPrice, p.LowestPrice, p.Image
                  , p.BackgroundColor, p.FontColor, p.buttonPositionCSS, p.isFromFeed, p.isDeleted, p.LastFeedUpdate, p.Created, p.CreatedBy, GETUTCDATE(), 'Feed Sync Process'
          FROM Product p
         WHERE p.isDeleted = 1
           AND p.CompanyID = @cid

        -- Needs DELETE -----------------------------------------------------------------------------------------------------------------------------------------------------------
        PRINT '--[ DELETE #1 ]--'
        DELETE FROM Product
         WHERE CompanyID = @cid
           AND isDeleted = 1

        -- Needs INSERT -----------------------------------------------------------------------------------------------------------------------------------------------------------
        PRINT '--[ INSERT ]--'
        INSERT INTO Product(ProductId, alternateProductID, CompanyID, CharacterId, URLDomain, SKU, Title, Description, ButtonConfig, RetailPrice, LowestPrice, Image
                  , BackgroundColor, FontColor, buttonPositionCSS, isFromFeed, isDeleted, LastFeedUpdate, Created, CreatedBy)
        SELECT NEWID()
             , a.AutoID
             , @cid
             , ''
             , ''
             , a.StockNumber
             , ''
             , ''
             , ''
             , a.ListPrice
             , a.GuaranteedSalePrice
             , COALESCE(a.ImageURL, '')
             , ''
             , ''
             , ''
             , 1
             , 0
             , a.Updated
             , GETUTCDATE()
             , 'Feed Sync Process'
          FROM RIVFeeds..AutoWithImage a
         WHERE a.ClientID = @ClientID
           AND a.StockNumber NOT IN (SELECT p.sku FROM Product p WHERE CompanyID = @cid AND isFromFeed = 1)
           AND a.AutoID NOT IN (SELECT p.alternateProductID FROM Product p WHERE CompanyID = @cid AND isFromFeed = 1)
           AND a.Active = 1

        --PRINT @cid

        FETCH NEXT FROM c1 INTO @cid
    END
    CLOSE c1
    DEALLOCATE c1
END
GO

Now I am writing it in code utilizing Entity Frameworks (not completed yet):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RivWorks.Model;
using RivWorks.Model.Entities;
using RivWorks.Model.Feeds;
using RivWorks.Model.RivData;
using model = RivWorks.Model.Entities;

namespace RivWorks.Controller.Sync
{
    public static class Feeds
    {
        #region Public Methods
        public static bool Product(long ClientID)
        {
            bool retFlag = true;
            DateTime startTime = DateTime.Now;
            DateTime splitTime = startTime;
            Guid companyID;
            DateTime createdUpdated = DateTime.UtcNow;
            string createdUpdatedBy = "Feed Sync Process";
            List<SyncMessage> Activity = new List<SyncMessage>();
            List<model.Product> insertProductList = new List<Product>();
            List<model.Product> updateProductList = new List<Product>();
            List<model.Product> deleteProductList = new List<Product>();

            using (RivEntities _dbRiv = new RivWorksStore(Stores.RivConnString).NegotiationEntities())
            {
                using (FeedsEntities _dbFeed = new FeedStoreReadOnly(Stores.FeedConnString).ReadOnlyEntities())
                {
                    List<model.AutoWithImage> feedProductList = _dbFeed.AutoWithImage.Where(a => a.ClientID == ClientID).ToList();
                    List<model.vwCompanyDetails> companyDetailList = _dbRiv.vwCompanyDetails.Where(a => a.ClientID == ClientID).ToList();

                    foreach (model.vwCompanyDetails companyDetail in companyDetailList)
                    {
                        companyID = companyDetail.CompanyId;
                        List<model.Product> rivProductList = _dbRiv.Product.Include("Company").Where(a => a.Company.CompanyId == companyID).ToList();

                        #region Handle UPDATES...
                        var updateFeedProductList = from f in feedProductList
                                                    join r in rivProductList
                                                    on f.AutoID equals r.alternateProductID
                                                    where f.Updated > r.LastFeedUpdate.Value || f.Active == false
                                                    select f;
                        var updateRivProductList = from r in rivProductList
                                                   join f in feedProductList
                                                   on r.alternateProductID equals f.AutoID
                                                   where f.Updated > r.LastFeedUpdate.Value || f.Active == false
                                                   select r;

                        foreach (model.AutoWithImage feedProduct in updateFeedProductList)
                        {
                            bool alreadyExists = false;
                            foreach (model.Product rivProduct in updateRivProductList)
                            {
                                if (feedProduct.StockNumber == rivProduct.SKU && feedProduct.AutoID == rivProduct.alternateProductID)
                                {
                                    alreadyExists = true;

                                    // Active feed items...
                                    if (feedProduct.Active)
                                    {
                                        // Changed since last sync...
                                        if (feedProduct.Updated > rivProduct.LastFeedUpdate)
                                        {
                                            rivProduct.ProductId = rivProduct.ProductId;
                                            rivProduct.Company = rivProduct.Company;
                                            rivProduct.alternateProductID = feedProduct.AutoID;
                                            rivProduct.Description = String.Empty.EnforceNoNull();
                                            rivProduct.Image = feedProduct.ImageURL.EnforceNoNull();
                                            rivProduct.isDeleted = false;
                                            rivProduct.isFromFeed = true;
                                            rivProduct.LastFeedUpdate = feedProduct.Updated;
                                            rivProduct.LowestPrice = feedProduct.GuaranteedSalePrice;
                                            rivProduct.RetailPrice = feedProduct.ListPrice;
                                            rivProduct.Title = String.Empty.EnforceNoNull();
                                            rivProduct.Updated = createdUpdated;
                                            rivProduct.UpdatedBy = createdUpdatedBy;
                                        }
                                        // Not changed since last sync...
                                        else if (feedProduct.Updated <= rivProduct.LastFeedUpdate)
                                        {
                                            // nop
                                        }
                                    }
                                }
                            }
                        }
                        _dbRiv.SaveChanges();
                        #endregion

                        #region Handle DELETES...
                        List<model.Product> deleteRivProductList = _dbRiv.Product
                                                                         .Include("Company")
                                                                         .Where(a => a.Company.CompanyId == companyID
                                                                                  && a.isDeleted == true)
                                                                         .ToList();
                        // transfer to ProductDelete table...
                        foreach (model.Product delProduct in deleteRivProductList)
                        {
                            model.ProductDeleted productDeleted = new ProductDeleted();
                            productDeleted.alternateProductID = delProduct.alternateProductID;
                            productDeleted.BackgroundColor = delProduct.BackgroundColor;
                            productDeleted.ButtonConfig = delProduct.ButtonConfig;
                            productDeleted.buttonPositionCSS = delProduct.buttonPositionCSS;
                            productDeleted.CharacterId = delProduct.CharacterId;
                            productDeleted.CompanyID = companyID;
                            productDeleted.Created = delProduct.Created;
                            productDeleted.CreatedBy = delProduct.CreatedBy;
                            productDeleted.Description = delProduct.Description;
                            productDeleted.FontColor = delProduct.FontColor;
                            productDeleted.Image = delProduct.Image;
                            productDeleted.isDeleted = delProduct.isDeleted;
                            productDeleted.isFromFeed = delProduct.isFromFeed;
                            productDeleted.LastFeedUpdate = delProduct.LastFeedUpdate;
                            productDeleted.LowestPrice = delProduct.LowestPrice;
                            productDeleted.ProductId = delProduct.ProductId;
                            productDeleted.RetailPrice = delProduct.RetailPrice;
                            productDeleted.SKU = delProduct.SKU;
                            productDeleted.Title = delProduct.Title;
                            productDeleted.Updated = createdUpdated;
                            productDeleted.UpdatedBy = createdUpdatedBy;
                            productDeleted.URLDomain = delProduct.URLDomain;
                            _dbRiv.AddToProductDeleted(productDeleted);
                        }
                        int moves = _dbRiv.SaveChanges();

                        // delete the records...
                        foreach (model.Product delProduct in deleteRivProductList)
                        {
                            _dbRiv.DeleteObject(delProduct);
                        }
                        int deletes = _dbRiv.SaveChanges();
                        #endregion

                        #region Handle INSERTS...
                        // to be written...
                        #endregion
                    }
                }
            }
            return retFlag;  // remember to set this...
        }
        #endregion
    }
}

I know it’s a bit messy right now. I am including this so if anyone has suggestions on how to better clean this up, better ways to utilize EF to do this, etc, I would appreciate it. I know there are some very slick ways of doing joins across entities and would like to learn rather than shooting myself in the foot.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-14T14:22:35+00:00Added an answer on May 14, 2026 at 2:22 pm

    I’ve got running code in place now. Since no one else is answering I have to assume that I am heading in the right direction. Thanks.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 386k
  • Answers 386k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer You can use &lt; for < and &gt; for >… May 14, 2026 at 11:45 pm
  • Editorial Team
    Editorial Team added an answer For reliable use of query strings I've found you need… May 14, 2026 at 11:44 pm
  • Editorial Team
    Editorial Team added an answer You need a version of the OpenSSL that is built… May 14, 2026 at 11:44 pm

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.