Verify unique constraint...

Posts   
 
    
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 26-Feb-2007 19:32:06   

ASP.NET, LLBLGen 2.0.7.111

The CustomerId is a foreign key to another table and we just want to make sure that ReferenceNumber is not duplicated by Customer.

So, I have a unique constraint on those two fields - CustomerId and ReferenceNumber.

All works fine.

Now, when the customer is inputting data and hits the save button, I want to verify this is unique BEFORE attempting to save so I can give a nice error message. I had hoped to do this in the InsertEntity() and UpdateEntity() overload.

I put the folllowing code in place. This causes Save() to return false if it fails for this reason and the entity will be loaded with the duplicate one. Works fine.

        protected override bool InsertEntity()
        {
            RequestEntity requestEntity = new RequestEntity();
            requestEntity.FetchUsingUCReferenceNumberCustomerId(this.ReferenceNumber, this.CustomerId);
            if (!requestEntity.IsNew)   //we found it...
            {
                ////TODO have to refetch???  There should be a better way!
                this.FetchUsingUCReferenceNumberCustomerId(this.ReferenceNumber, this.CustomerId);
                return false;  //do not save anything!
            }
            return base.InsertEntity();
        }

Now, when they updated a record, I needed to make sure they did not change the ReferenceNumber to one that already existed, so I put similar code in for that.

Problem is there is specific code on the support classes that cause an exception to be thrown if the Save() returns false AND it is an update! If it is an insert, the exception is not thrown.

What are the suggestions on how to implement the above behavior. I was planning on implementing this in the DataLayer - I want it to fail the save, but fail politely.

jmeckley
User
Posts: 403
Joined: 05-Jul-2006
# Posted on: 26-Feb-2007 22:52:55   

It appears your using the SS model, not adapter. Instead of overriding the InsertEntity function use the ValidateEntityBeforeSave function. 1. Check if the entity IsNew. this determines insert/update true/false. 2. Throw an ORMEntityValidationException. 3. Catch the ORMEntityValidationException in the BLL/GUI and log/display the exception message.

I pretty sure the SS model incorporates the validation framework by default.

Posts: 1268
Joined: 10-Mar-2006
# Posted on: 27-Feb-2007 03:47:40   

Yeah, I wondered if I should be doing that. I assume I can throw my own custom exception so that I know exactly what I am catching and such, right?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Feb-2007 06:34:12   

Check the LLBLGen Pro manual: Using the generated code -> Validation per field or per entity

Pay attention to the last section: IDataErrorInfo implementation You can use SetEntityError to write a nice error message that can be displayed/catched in the GUI.

Posts: 1268
Joined: 10-Mar-2006
# Posted on: 27-Feb-2007 15:21:40   

I have read that. However, I need more than an error message. I need data - fields from the duplicate matching record, which is why I would want to throw a custom exception.

Are you saying I cannot do that?

Also, I have read alot of posts here on that and there appear to be a bunch of issues with the errors being cleared out, no support in asp.net, etc?

Also, why would the base library throw an exception on update but not on insert when the save returns false?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 27-Feb-2007 15:52:24   

It throws an exception on update because the situation in which save would return false is when a concurrency exception occured, i.e. 0 rows affected. WIth insert that's not the case, you can't have a concurrency exception on insert.

If you want to be sure the value is unique, do that from a validator, and there fetch the id using a scalar fetch (or whatever fetch you want to use).

This isn't 100% fail proof, as there is always a possibility that a modification by another thread is done between your test and your actual save action.

So for unique failures, you need to catch exceptions for unique constraint failures anyway after the save completed.

You can throw an exception whatever you want. The IDataErrorInfo interface implementation doesn't have issues, you just have to make sure you clear the collection if you want to get rid of previous error messages. ASP.NET support is just fine, though IDataErrorInfo is a bit of a weird interface and it's mostly used in winforms apps.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 1268
Joined: 10-Mar-2006
# Posted on: 27-Feb-2007 15:57:53   

Ok - thanks Otis. I will try this approach.

Thanks for everyones help.