0

Using C# and MongoDb im saving a class similar to the following.

public class Zone
{
    public string ZoneName { get; set; }
    public List<string> IncludedCountries { get; set; } = new List<string>();
}

This is filled by user and saved in my DB, currently I am checking that the zone name isn't duplicated when inserting. Like so. if (All().Any(x => x.Name.ToLower() == zone.Name.ToLower())) { throw new System.Exception($"Zone \"{zone.ZoneName}\" is already in database, please edit the zone"); };

But if user currently tries to add the exact same values (So exact same list of included countries) with different name, I wouldn't catch it. I want to be able to, as dont want to be duplicating same classes in DB (My actual class will have more properties, this is an example). I am aware I can check it the same way im checking for name, but having in mind I have a lot of properties, i'd like to know what the best way is..

Luciano F
  • 63
  • 7
  • You shouldn't check for duplicate records by running a search. You should set up a constraint on the database, so that, if you try and save a record, you will get an exception. They way your current code is written, it's possible that between you checking and actually saving the record, that a duplicate has been created. – Neil Jun 03 '21 at 08:59

1 Answers1

0

Ideally you wouldn't perform a search, then use that to decide whether to add or not. In a collaborative system with potentially multiple users you could find another user in another transaction runs the same code at the same time, and ends up adding the record just after your check, but just before your insert.

It's better, assuming your datastore supports it, to use a uniqueness constraint on some value of the data you're inserting. Here's the docs for Mongo: https://docs.mongodb.com/manual/core/index-unique/

This means the transaction will be failed by the database if you attempt to insert a duplicate. To be fair, there's nothing wrong with doing the "ask-then-tell" as well I suppose, in order to avoid ugly exceptions being shown to users, but if you're able to interrogate the exception details you can probably catch it and show the user some helpful information rather than letting them see an error page.

To support your requirement for "has the same list of things" in this way, I'd suggest creating a SHA256 hash value (here's a link: https://stackoverflow.com/a/6839784/26414) for the list, and storing that as a property in it's own right. Just make sure it's recalculated if the list changes.

One additional thing - technically "class" defines the schema, or shape of a bit of data. When you create an instance of a class at runtime, which has actual values and takes up memory, that's technically an "object". So an "object" is an "instance" of a "class".

Neil Barnwell
  • 41,080
  • 29
  • 148
  • 220