Skip to content

Conversation

sharafabacery
Copy link

@sharafabacery sharafabacery commented Jul 26, 2025

Description

Important topics to cover include:
Enable Passing Empty List of type SqlDataRecord and make it functionality like when value is null

  • Description of the functionality.
    I remove exception from SqlParameter.cs and in SqlCommand I figure where it if parameter is null what happen and adding small condition

Issues

Fixes issue #2971

Testing

I create database and delete it when test finish to make test work and
first test when list is empty and second one when it null and it works correctly
Screenshot 2025-07-25 025730
and this photo captured from my sql server profiler to prove that it sends default

@sharafabacery sharafabacery requested a review from a team as a code owner July 26, 2025 10:08
Copy link
Contributor

@benrr101 benrr101 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking a stab at working on this issue. It needs a lot of work though... Please take a look at the comments and let me know your thoughts.

}

if (!_pendingCancel)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this change at all, especially since they seem to be completely unrelated to the focus of the PR. We don't want to be removing braces for if statements, and in this particular instance it completely upends the logic of the method.

asyncWrite,
isRetry,
methodName);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't really help readability.

{
completion.TrySetResult(retryTask.Result);
}
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change also makes no sense, and I don't see how it compiles at all. Why was this change made?

}

/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/ExecuteXmlReaderAsync[@name="default"]/*'/>
public Task<XmlReader> ExecuteXmlReaderAsync() =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change seems completely random, unrelated to the focus of the PR, and likely doesn't compile.

task: out unused,
usedCache: out _,
method: method);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, removing this line doesn't really aid readability and is unrelated to the PR focus.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All changes above could be because I enable formatting document after saving
@benrr101

}
}

#region fixing "Change SqlParameter to allow empty IEnumerable<SqlDataRecord>? #2971"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what to do about these tests. I think someone with a bit more experience in the test area could provide more concrete feedback. @mdaigle ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All changes above could be because I enable formatting document after saving

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there any test need to be done i will do it?

@sharafabacery sharafabacery requested a review from benrr101 July 30, 2025 19:53
@edwardneal
Copy link
Contributor

Without wanting to step on @benrr101's toes, does this address the issue and support IEnumerable<SqlDataRecord>?

I've written a simple test - gist for it is here. This test returns an enumerator which isn't backed by an ICollection (and can't be - it's an iterator method.) The test as-is fails with the error:

The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Table-valued parameter 1 ("@tvp"), row 0, column 0: Data type 0xF3 (user-defined table type) is null and not set to default. A null table-valued parameter is required to be sent as a default parameter.

One possible approach which might allow iterator methods to work is here. It's enough to prove the principle and hopefully it helps a little, but it's definitely not complete. For a quick overview:

  • We add an explicit Empty flag to the structure which holds the peekahead information, indicating that the enumerator is empty.
  • I took this slightly further and have a shared EmptyPeekahead instance so that we're not creating a large number of objects.
  • SqlParameter.GetActualFieldsAndProperties is the only method which populates this peekahead structure. Rather than throwing SQL.IEnumerableOfSqlDataRecordHasNoRows, we set the peekahead to EmptyPeekahead.
  • TdsParser.WriteSmiParameter is the only method which calls GetActualFieldsAndProperties and does anything with the peekahead information. It also has a sendDefault parameter, so we make sure that if the Empty flag on the peakahead is set, sendDefault is also forced to true. My test started to pass.
  • Since we no longer used the SQL.IEnumerableOfSqlDataRecordHasNoRows method, I deleted it.
  • I added the test in the gist to prove that this works. It passes on .NET Core.

I've not ported this over to the .NET Framework version. I've also only tested this in one specific situation - it's worth testing to prove this behaves properly with multiple table-valued parameters, empty lists, empty arrays and any other situations which come to mind. I'm sure there'll be some feedback on the way the test is written too - it's just to demonstrate the existing code which eliminates the need to create and drop databases manually.

@sharafabacery
Copy link
Author

@edwardneal so impressive what you do,IF I need to still on this issue i need to do? what i need to learn? to complete this issue?

@edwardneal
Copy link
Contributor

Sorry for the delayed response. I think we're dealing with the problem in nearly the same place - the difference here is that your approach sets the options variable correctly in the first instance (based on the type of the parameter) while my approach changes the way that TdsParser responds to that variable a little later in the process (based on whether the IEnumerable has a value.)

I think the EmptyDynamicIEnumerableShouldPassDefault test will prove whether or not #2971 has been fixed (although benrr101 or mdaigle might have some extra feedback.) I'd suggest reverting the changes to SqlCommandTest.cs and using EmptyDynamicIEnumerableShouldPassDefault as your test case to prove whether or not the issue is fixed.

Ben's already pointed out a few of the unrelated changes to SqlCommand.cs, those need to be reverted. Once that's done (and the PR only contains the needed changes) then you can find a working method to fix the problem. After you've found that method, just make sure the two SqlCommand code files (one in netcore and one in netfx) have been changed in the same way.

This reverts commit 1d6ee75.
@sharafabacery
Copy link
Author

@edwardneal thanks for help,curently I working on it by solution based on my previous one if your testcase fail i will try yours beacuse we try soolve the same problem and each of us look on it some respective, but whenI fetch orgin and run testcases and it build the package it responed with errors
Metadata file 'source\repos\SqlClient\artifacts\Project\bin\Windows_NT\Debug.AnyCPU\Microsoft.Data.SqlClient\netcore\net8.0\Microsoft.Data.SqlClient.dll' could not be found
and there is some syntax error I showed

@paulmedynski
Copy link
Contributor

/azp run

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@benrr101 benrr101 changed the title fix #2971 Fix | Pass Empty List for SqlDataRecord (#2971) Sep 16, 2025
@benrr101
Copy link
Contributor

This PR doesn't compile in its current state, and it has merge conflicts with the current main branch. Please let us know what you want to do with it in the next week otherwise we'll probably close this PR.

@sharafabacery
Copy link
Author

@benrr101 close this issue the project in my machine doesn't compile also for that I will stop in this issue,I am sorry if I waste your time

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.

5 participants