Is there a way to speed up the Linq.Any check or perform the check in another way to enhance performance.
I have a mastercodes table that records unique codes for a campaign. The code below will create new codes for a campaign but checks the mastercode table to make sure that it doesn;t already exist. Once the codes have been created and added to the mastercodes table it creates an excel file for download.
The main issue is that a campaign can have 400k codes and we have several campaigns running at once. So the mastercode table can get into the millions of records. When I request 300 new codes and run the below process without the .Any() check it takes 1-2 seconds in production. However when i add the check the process times out with the "no response to user" timeout error.
I'm using the Z.EntityFrameworrk.Extensions and the post to the table happens pretty much instantly. But is there a way to code the perform the mastercode check that doesn't have a huge performance issue.
The Model
public class MasterCode
{
public int MasterCodeId { get; set; }
public int CampaignId { get; set; }
public string CampaignCode { get; set; }
public string Code { get; set; }
public bool Used { get; set; }
public DateTime SubmittedOn { get; set; }
}
The code
public static void GenerateMasterCodes(GenerateMasterCode model)
{
using (ApplicationDbContext _context = new ApplicationDbContext())
{
Campaign campaign = _context.Campaigns.Find(model.CampaignId);
List<MasterCode> masterCodes = new List<MasterCode>();
for (var i = 1; i <= model.Count; i++)
{
var masterCode = new MasterCode
{
CampaignId = campaign.CampaignId,
CampaignCode = campaign.CampaignCode,
Used = false,
SubmittedOn = DateTime.Now
};
// Ensure that no code already exists for that campaign.
var code = GenerateMasterCode(model.StartString, model.CodeLength);
while (_context.MasterCodes.Any(m => m.Code == code && m.CampaignCode == campaign.CampaignCode))
{
code = GenerateMasterCode(model.StartString, model.CodeLength);
}
masterCode.Code = code;
masterCodes.Add(masterCode);
}
try
{
_context.MasterCodes.AddRange(masterCodes);
_context.BulkSaveChanges();
}
catch (Exception ex)
{
...
}
}
}
The Code generator
public static string GenerateMasterCode(string startString, int mastercodeLength)
{
string numericChars = "X123456789";
char[] chars = new char[mastercodeLength];
Random rd = new Random();
for (int i = 0; i < mastercodeLength; i++)
{
if (!string.IsNullOrEmpty(startString) && i < startString.Length)
{
chars[i] = Char.Parse(startString.Substring(i, 1));
}
else
{
chars[i] = numericChars[rd.Next(0, numericChars.Length)];
}
}
return new string(chars);
}
model.StartString
whichLength
equals tomodel.CodeLength
? \$\endgroup\$ – Heslacher Apr 12 '17 at 6:05