0

After this answer :

Why are these hashcodes equals?

I realized that GetHashCode intend is not to provide a unique identifier for an object.

The purpose of this test was that I have a business function with 6 parameters :

  • customerId
  • serviceId
  • startDate
  • EndDate
  • cmsThematicId

And I don't want to be able to call this function more than once with the same values

These parameters are inserted in the database, I could query with (customerId = @customerId and serviceId = @serviceId ...), but I need to be efficient with a lot of combination so this is not a solution.

Edit :

Example :

Let's say I have a super user he need to register customers. A registration is made of 5 parameters : customerId, serviceId, startDate, EndDate, cmsThematicId. The process of registering is like this :

  • you select the service (for instance "show hi with a big red button")
  • you select the customer (who bought the service)
  • you select the cmsThematicId (the web page if you want)
  • you select the startDate (in a drop down list)
  • you select the endDate (in a drop down list)

My form can't show a set of parameters that was already used.

For instance once the customer 1 is registered for the service "big red button" on the page "holidays in new york" for the month of january, the super user won't be see these set of parameters in the form.

So my process did this : - create all the possibility - compute each possibility's hashcode in a List - get the hashcode of each already used possibility (from the db) - remove the already used possibility from the list - display the form

problem is : hashcode are not unique , so I might remove a item even if it was not used.

is it clearer ?

Community
  • 1
  • 1
remi bourgarel
  • 9,231
  • 4
  • 40
  • 73
  • 6
    It's not clear what you mean. If they're inserted into the database, and you put a uniqueness constraint on the database (or just indexes and do a query) it should be fine. What do you mean by "I need to be efficient with a lot of combination"? – Jon Skeet Jan 30 '13 at 08:54
  • I'm building a form showing all the parameters combination, but I can't show a parameters already used, so this computing has to be done prior to the inserting. – remi bourgarel Jan 30 '13 at 08:56
  • Why can't you just do a query before you insert? Or try to insert and handle the unique constraint violation? – Jon Skeet Jan 30 '13 at 08:57
  • I might show 2000 different parameter combination in my form so running 2000 query filtering on 5 fields is not an option. Second question : I don't want my user to have to try many combination saying "nope it's not possible try something else" – remi bourgarel Jan 30 '13 at 09:00
  • "Second question : I don't want my user to have to try many combination saying nope it's not possible try something else" - I am not sure this could ever be possible; how can you know they are not unique without checking and reporting to the user? – Ryan Jan 30 '13 at 09:30
  • let's say you have a form suggesting dates for registering : 1Jan, 2 Jan, 3 Jan. if you are already registered for 3Jan, I don't want to show you 3Jan, Jon's solution is : if the user selects 3Jan then I'll display an error. – remi bourgarel Jan 30 '13 at 09:44
  • Okay, it's still not clear at all to me what's prohibited. I thought it was only the *combination* of values. If you're saying that each *individual* value can't be repeated (i.e. once you've used a customerId once, you can never have any record using that customer ID) then it's a different matter. But basically your question is still very confusing, IMO. – Jon Skeet Jan 30 '13 at 09:47
  • i'll edit my post to make it clearer – remi bourgarel Jan 30 '13 at 09:48

1 Answers1

0

After each call, store your 6 values in a history table with a composed index. In your business function I would add a code to verify if those values are already in your history table and immediately exit if I found those values.

LATER EDIT: This is how you should query the History table:

IF EXISTS
  (SELECT customerId FROM HIstory WITH (NOLOCK) WHERE customerId='<value>' AND serviceId='<value>' AND <add all your fields here>)
    SELECT 1
ELSE
    SELECT 0

This way, if there is already a record (meaning your business function has been already called with the params you are testing), the above query returns 1, otherwise 0.

So if 1, you need to stop.

If 0, you need to add the values to history table and execute the business logic. OR: execute the business logic THEN add the values to history table.

EDIT2: Initially, your History table is empty. Each call to your function will:

  1. Query the Hitory table for existing values that match the values passed as parameters to your function

  2. Populate the History table if needed.

That is, first thing your function does is to query the History table and (if needed) to insert a new set of values in that table. Basically the query will get executed each time you call the function you implemented because the query is done inside that function.

Adi
  • 5,113
  • 6
  • 46
  • 59
  • the problem here is that I might have 2000 values and there is 5 fields (some of them are dates), so this could be long even with an index. – remi bourgarel Jan 30 '13 at 09:04
  • 2
    no way, you underestimate the power of sql server and indexes :) this is actually a low number, believe me – Adi Jan 30 '13 at 09:05
  • 2000 is in fact the lower bound, for getting my double hascodes I had to build 31110 combinations. How would you (in sql) query your database ? – remi bourgarel Jan 30 '13 at 09:08
  • I mean, I understand that there could be possibly millions of combinations... but you should test this first on the largest set of data you may think of – Adi Jan 30 '13 at 09:08
  • Just a simple SELECT ... WITH (NOLOCK) on those 5 fields – Adi Jan 30 '13 at 09:09
  • And regarind this history table: if the frequency of querries vs frecquency of inserts is very big, then defining a composed index over all 5 fields helps you speed things up when you do the query. – Adi Jan 30 '13 at 09:13
  • I select all the values in the db, and then with c# compare those to the ones I calculated ? – remi bourgarel Jan 30 '13 at 09:13
  • 1
    no no no, use IF EXISTS: IF EXISTS(SELECT customerId FROM HIstory WITH (NOLOCK) WHERE customerId='' AND serviceId='' AND ....) http://blogs.msdn.com/b/miah/archive/2008/02/17/sql-if-exists-update-else-insert.aspx – Adi Jan 30 '13 at 09:17
  • let me add a full working query to my answer, so that it is more clear to you – Adi Jan 30 '13 at 09:23
  • So i'll run your query 31110 times (once for each combination) ? – remi bourgarel Jan 30 '13 at 09:31
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/23627/discussion-between-adi-and-remi-bourgarel) – Adi Jan 30 '13 at 09:40
  • 1
    my solution is only to solve your future problems, not the bad design you did in the past, sorry. Unfortunately from your hash values you cannot tell what were the actual values that produces those hashes, so my solution is to change everything you did so far and replace it with this history table. – Adi Jan 30 '13 at 09:44