Why does this controller double the inserts when I try to archive the results of the Bing Search API?

131 views Asked by At

I'm trying to archive my search results for a term by

  1. Using the Bing API in an async controller
  2. Inserting them into database using Entity Framework

using the Bing API and insert them into a database using entity framework. For whatever reason it is returning 50 results, but then it enters 100 results into the database.

My Controller Code:

public class DHWebServicesController : AsyncController
    {
        //
        // GET: /WebService/

        private DHContext context = new DHContext();


        [HttpPost]
        public void RunReportSetAsync(int id)
        {
            int iTotalCount = 1;
            AsyncManager.OutstandingOperations.Increment(iTotalCount);
            if (!context.DHSearchResults.Any(xx => xx.CityMarketComboRunID == id))
            {

                string strBingSearchUri = @ConfigurationManager.AppSettings["BingSearchURI"];
                string strBingAccountKey = @ConfigurationManager.AppSettings["BingAccountKey"];
                string strBingUserAccountKey = @ConfigurationManager.AppSettings["BingUserAccountKey"];
                CityMarketComboRun cityMarketComboRun = context.CityMarketComboRuns.Include(xx => xx.CityMarketCombo).Include(xx => xx.CityMarketCombo.City).First(xx => xx.CityMarketComboRunID == id);

                var bingContainer = new Bing.BingSearchContainer(new Uri(strBingSearchUri));
                bingContainer.Credentials = new NetworkCredential(strBingUserAccountKey, strBingAccountKey);
                // now we can build the query

                Keyword keyword = context.Keywords.First();
                var bingWebQuery = bingContainer.Web(keyword.Name, "en-US", "Moderate", cityMarketComboRun.CityMarketCombo.City.Latitude, cityMarketComboRun.CityMarketCombo.City.Longitude, null, null, null);
                var bingWebResults = bingWebQuery.Execute();

                context.Configuration.AutoDetectChangesEnabled = false;

                int i = 1;
                DHSearchResult dhSearchResult = new DHSearchResult();
                List<DHSearchResult> lst = new  List<DHSearchResult>();
                var webResults = bingWebResults.ToList();
                foreach (var  result in webResults)
                {
                    dhSearchResult = new DHSearchResult();
                    dhSearchResult.BingID = result.ID;
                    dhSearchResult.CityMarketComboRunID = id;
                    dhSearchResult.Description = result.Description;
                    dhSearchResult.DisplayUrl = result.DisplayUrl;
                    dhSearchResult.KeywordID = keyword.KeywordID;
                    dhSearchResult.Created = DateTime.Now;
                    dhSearchResult.Modified = DateTime.Now;
                    dhSearchResult.Title = result.Title;
                    dhSearchResult.Url = result.Url;
                    dhSearchResult.Ordinal = i;
                    lst.Add(dhSearchResult);
                    i++;
                }

                foreach (DHSearchResult c in lst)
                {
                    context.DHSearchResults.Add(c);
                    context.SaveChanges();

                }
                AsyncManager.Parameters["message"] = "The total number of results was "+lst.Count+".  And there are " + context.DHSearchResults.Count().ToString();
            }
            else
            {
                AsyncManager.Parameters["message"] = "You have already run this report";
            }
            AsyncManager.OutstandingOperations.Decrement(iTotalCount);
        }
        public string RunReportSetCompleted(string message)
        {
            string str = message;
            return str;
        }

    }

Here is how I am calling it from my asp.net mvc 4 page.

@Ajax.ActionLink("Run Report", "GatherKeywordsFromBing", "DHWebServices", 
                new { id=item.CityMarketComboRunID}, 
                new AjaxOptions { OnSuccess = "ShowNotifier();", UpdateTargetId = "TopNotifierMessage", HttpMethod = "POST", InsertionMode = InsertionMode.Replace, LoadingElementId = strCityMarketComboProgressID, LoadingElementDuration = 1000 }, 
                new { @class = "ViewLink" }) 
            <span class="ProgressIndicator" id="@strCityMarketComboProgressID"><img src="@Url.Content("~/Content/img/SmallBall.gif")" alt="loading" /></span>

For whatever reason all of

1

There are 1 answers

1
Darin Dimitrov On

Try saving only once:

foreach (DHSearchResult c in lst)
{
    context.DHSearchResults.Add(c);
}
context.SaveChanges();

Also there's nothing asynchronous in your code, so there's no point of using asynchronous controller. Not only that it won't improve anything but it might make things worse.