Best Criteria practices

Best Criteria practices

Old forum URL: forums.lhotka.net/forums/t/214.aspx


Aliator posted on Sunday, May 28, 2006

Hi,

I wonder what is the best method for handling multiple criteria for on object...

I have a list of items that I want to filter by category in my frontend... So I only have to pass the Id of the category to my list object...

But in backend, I  need to have all the categories in the list... From object view is simple, I overload my GetObjectList to accept an id or to accept nothing...

But, how do you handle in DataPortal_Fetch ?

Do you analyze Criteria object and then use SP_WithIdParamater or SP_WithoutParameter ?

Or do you manage this in the SP itself ?

TIA

dean replied on Sunday, May 28, 2006

If it is as simple as this I would use 1 stored proc but I don't think there is a big difference either way. If you start needing many different criteria for complicated queries there are many posts in the old forum about this with several different strategies.. You may want to search at www.searchcsla.com for "complex" and "criteria" and browse.

Dean

Jav replied on Sunday, May 28, 2006

I am sure there are many ways to handle this. Here is what I have done, and it has worked well.

In the StoredProc:
Each of the arguments has a default value, like Null or "" or 0 etc.  Then in the where clause, I check to see if an argument has default value before using in the expression like:
      Where ((@ID is Null) or (Person_Id = @ID))

In DataPortal_Fetch:
I check each optional parameter for a default value before calling AddWithValue() for that parameter.  This assures that in the SP only the arguments I send will be evaluated against.

In Criteria Class:
Each instance variable is assigned a Default Value which I check against in the DataPortal_Fetch.  If no value is assigned in the Criteria Constructor, the default will be automatically sent.

In the Shared GetList method(s):
I create either Overloads or use Optional Arguments to send exactly what the criteria need.

Jav

miroslav replied on Monday, May 29, 2006

I've used a similar approach as Jav. The only difference is that my Where clause looks like this:
WHERE Person_Id = ISNULL(@ID, Person_Id)

... but the result is the same.

Aliator replied on Tuesday, May 30, 2006

Thank you for the tips...

www.searchcsla.com was very helpfull too.

Dog Ears replied on Thursday, May 31, 2007

Just stumbled across this old(ish) post, thought i'd add something for completeness.

Something like the above SQL would be non-SARGable [on SQL2K at least] I played around with the following and the second SQL took 600 times longer [although they both returned data within a second..! but if you scale up..?!?!]

declare @id int
set @id = 254765
select * from tblshiftrecords where shiftid = @id
select * from tblshiftrecords where shiftid = isnull(@id, shiftid)

The table here has is quite small only abut 300K records and shiftid is the Clustered primary key.

The first SQL performs a SEEK the second a SCAN...!

This could be an important consideration when chosing a solution,

Regards,

Graeme.

DansDreams replied on Thursday, May 31, 2007

Hey Dog Ears, thanks for that post.  I didn't realize that the SQL optimizer will never bother looking for an index to use with isnull() or coalesce().

I did know that you also have a similar potential performance problem creating a stored procedure that just creates a dynamic ad hoc query string and executes it, since SQL Server can't cache an execution plan for the sproc.

This is all part of why I've never really bought into the idea of jumping through all these hoops to be able to mandate the use of sprocs for all reading of data, but that's just my opinion.

BTW, does SQL 2005 have any functionality whereby if you change a column name it will tell you all the sprocs you just broke (or change them)?

rdrunner replied on Wednesday, June 06, 2007

Hello....

 

About the performance issue...

 

You should never use a function or calculate with a field from a table. This will void all indexes and every record has to be evaluated so this will result in an index or table scan like already posted.

Example (Showing last weeks orders):

... Where orderdate + 7 > getdate (No index can be used. The calculation needs to be done for every record)

... Where orderdate > getdate -7  (Index can be used.Calculation only needs to be done once)

Or how to solve an "optional" Filter field:

where (myParam is null OR myfield = myParam)

ajj3085 replied on Wednesday, June 06, 2007

I wouldn't say "never."  I have a few views that are include a function call in the select clause, and the performance is still very fast.

You do have to be careful though, it depends on what the function does.  We did run into a case where a function in the select clause was slow enough to cause problems.

As for the where clause, I would take your second clause and use a variable there that stores the result of getdate - 7, that way the calcuation is done only once and its just a compare. Also, I'm not sure that if you have a long enough running query that getdate won't start returning different values as the result set is built.  If the -7 is the number of days, its not problem, but if its milliseconds you may have a problem..

yimiqi replied on Saturday, June 02, 2007

I also wanted to search some info on www.searchcsla.com site, but it doesn't have a search feature (or i missed it somehow), instead on the main page it says

This site is a tool --- use it in conjunction with your telephone conference calls.

How do I do search on this site (I know it sounds a pretty strange question)?  Thanks.

 

Brian Criswell replied on Sunday, June 03, 2007

It looks like someone has taken over the domain.  I think that site used to search the old msn forum.  Just use the search box in the top right corner of any page on this site.

Copyright (c) Marimer LLC