0

I am trying to create a unique random number. If the random number exists in the database, loop through the block of code again until it finds a number that does not exist. Save value to database. Any help on this would be great. Thank you.

public IHttpActionResult BookMatch(int id)
{
    Guid guid = Guid.NewGuid();

    var user = User.Identity.GetUserId();
    var getuser = db.AspNetUsers.Find(user);
    var match = db.Matches.Find(id);

    Random rnd = new Random();
    var peg = rnd.Next(match.PegRangeMin, match.PegRangeMax);

    var alreadyExists = db.Pegs.Any(x => x.MatchId == match.Id && x.PegNo == peg);

    if (alreadyExists == true)
    {
        //do something
    }

    var result = new Booked()
    {

        MatchId = id,
        BookerId = user,
        TicketNo = guid.ToString(),
        //pegNo = randompeg
    };

    db.Bookeds.Add(result);
    db.SaveChanges();

    if (result == null)
    {
        throw new Exception();
    }

    var getmatch = db.Matches.Find(id);

        var body = "<p>Email From: {0} ({1}) </p>" +
                   "<h3>Match Booking Confirmation:</h3>" +
                   "<b>Ticket Number:</b><p> {2} </p>" +
                   "<b>Venue:</b><p> {3} </p>" +
                   "<b>date and time:</b><p>{4}</p>";

        var message = new MailMessage();
        message.To.Add(new MailAddress(getuser.Email));
        message.From = new MailAddress("nicholas.mciver@Activeplan.co.uk");
        message.Subject = "Matchbooker Confirmation Email";
        message.Body = string.Format(body, getuser.GetFullName(), getuser.Email,
            result.TicketNo, getmatch.Fishery.Name, getmatch.DateTime);
        message.IsBodyHtml = true;

        using (var smtp = new SmtpClient())
        {
            smtp.Send(message);
        }

    return Ok();
}
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
  • You can make a recursive function (a function that calls itself). Generate a number and check the DB. If the generated number exists in the DB, call your function recursively. If it does not exist, you can insert into the DB and return out of the function. – Nolan Bradshaw Nov 05 '20 at 16:58
  • You either loop or you use recursion (like @NolanBradshaw suggested). Currently you throw an exception which will prevent retries. – David L Nov 05 '20 at 17:10
  • You will get a race if just after you determined that a number is still available, another user adds this very number. Depending on the DBMS you use, it might be better to use a stored procedure. – Klaus Gütter Nov 06 '20 at 06:09

1 Answers1

0

The simplest way is to do the number generation and the check in a while (true) loop:

int peg;

while (true)
{
    peg = rnd.Next(match.PegRangeMin, match.PegRangeMax);

    var alreadyExists = db.Pegs.Any(x => x.MatchId == match.Id && x.PegNo == peg);

    if (!alreadyExists) break;
}

This is not perfect because in case that all possible numbers are taken, the loop will never break. But this may not be a problem in practice, provided that the min-max range is sufficiently large.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
  • Thanks for this I was able to accomplish what I was looking to do with a continue rather than a break. If the number exists in the database then continue until if finds a number that isn't in the database. I then created a recursive function with this method. Thanks for your help. @Theodor Zoulias – Nicholas McIver Nov 08 '20 at 10:33
  • @NicholasMcIver you have probably a `break` somewhere, otherwise the loop would continue for ever. :-) – Theodor Zoulias Nov 08 '20 at 10:39
  • What if I make the booking impossible in the UI if all possible numbers exist with the matchId? – Nicholas McIver Nov 08 '20 at 10:43
  • @NicholasMcIver OK, you have a `return` instead of `break`. :-) Btw I suggest to move the creation of the `Random` outside of the loop. Look [here](https://stackoverflow.com/questions/1654887/random-next-returns-always-the-same-values) for an explanation why. – Theodor Zoulias Nov 08 '20 at 10:44
  • @NicholasMcIver if all numbers are taken, then you have a big problem. The loop will spin forever! – Theodor Zoulias Nov 08 '20 at 10:47