Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using a clone to prevent an error if the param is a SqlParameter, #272

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

dcrafti
Copy link

@dcrafti dcrafti commented Mar 22, 2016

...rather than a value type.

The error is "The SqlParameter is already contained by another SqlParameterCollection"

…her than a value type.

The error is "The SqlParameter is already contained by another SqlParameterCollection"
@pleb
Copy link
Member

pleb commented Mar 29, 2016

Hi @dcrafti, thanks for the contribute.

You're missing unit/integration tests to confirm the problem and the fix.

Also, if I understand this correctly, you're reusing SqlParameters in the multiple calls to PetaPoco? If so would the clone call be better placed in your code?

@dcrafti
Copy link
Author

dcrafti commented Mar 29, 2016

The issue that the code fixes is that if there is sql passed into PetaPoco
like:
"select a from b where x != @0 and x like '@0%'" (for example), then
PetaPoco, under the hood, converts that to "select a from b where x != @0
and x like '@1%'" and it fills in @1 by duplicating @0.
That's usually fine, but it interacts poorly when using SqlParameters (and
possibly other things).
Here's why: A SqlParameter (or other IDbParameter) is sometimes needed when
doing a query by an indexable varchar. It's needed in that situation
because just passing through a string as a parameter to PetaPoco will have
the string treated as an nvarchar, which will cause the index to not be
used.
The expansion, by default, results in @0 and @1 being references to the
same parameter. Adding the exact same parameter to the sql twice will fail
because the parameter has already been used.
As such, cloning the parameter, when it is cloneable, can be done to ensure
that it is always a different parameter being used.

If you want to replicate the broken behaviour, try running something like
this:
_db.Fetch("select 1 from [table] where @0 = 'test' and @0 != 'test'
", new SqlParameter { DbType = DbType.AnsiString, Value = "test" })
It doesn't matter about what's in the SQL. It only matters that one
IDbParameter is used twice.

On Tue, 29 Mar 2016 at 12:34 Wade Baglin [email protected] wrote:

Hi @dcrafti https://github.com/dcrafti, thanks for the contribute.

You're missing unit/integration tests to confirm the problem and the fix.

Also, if I understand this correctly, you're reusing SqlParameters in the
multiple calls to PetaPoco? If so would the clone call be better placed in
your code?


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#272 (comment)

@pleb
Copy link
Member

pleb commented Apr 1, 2016

No worries. When I get time I'll investigate and write a few integration tests the prove the bug

@asherber
Copy link
Collaborator

asherber commented Aug 3, 2022

@kurda-kurda I'm going to delete your comment, because it's not related to PetaPoco. If you have a question about general SqlParameter use, I suggest that you ask it on StackOverflow. I also suggest that you simplify your example and make sure it has all the relevant code. You've provided an entire class, which is probably not necessary, but you don't show how you're calling the class or where the exception is thrown.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants