WriteCommandError diagnostic event missing when using ExecuteReader when an OUTPUT clause is present
- Dominant language
- C#
- Stars
- 989
- Forks
- 340
- Avg merge
- 4d 18h
- Merged PRs (30d)
- 69
Description
When an `OUTPUT` clause is present in a query, such as in the following:
```sql
INSERT INTO [TestEntities] ([Property]) OUTPUT INSERTED.[Id] VALUES ('TestValue')
```
If that query is run using `ExecuteReader` (or `ExecuteReaderAsync`), any error created (such as violating a constraint) is not emitted as a diagnostic source event. Normally, the `Microsoft.Data.SqlClient.WriteCommandError` event would be emitted in such a case.
The error *is* emitted if the `OUTPUT` clause is not in the query, or if `ExecuteScalar` is used instead.
This is a problem because EF Core 7 has changed behavior to use an `OUTPUT` clause where it used to do a `SELECT` with `scope_identity()`, and it uses `ExecuteReader` because it sometimes asks for multiple return values. I originally brought this up as an EF Core 7 bug, but I believe it's actually a problem with SQL Client. See https://github.com/dotnet/efcore/issues/29543 for more detials.
### To reproduce
- Clone the repository at: https://github.com/mattjohnsonpint/sqlclient-diagnosticlistner-issue-repro
- Run the application and examine the output.
The application writes three rows to a table that has an identity column and another column that has a unique index. Because it uses the same value for each write, only the first insert succeeds. The second and third inserts fail due to the unique index being violated. When doing so, only the second insert is correctly logged by the diagnostic listener included with the app. The third insert is not logged. The only difference between them is that one omits the `OUTPUT` clause.
The app emits:
```
Inserting row...
Row inserted with ID = 1.
Inserting row...
Error: Cannot insert duplicate key row in object 'dbo.TestEntities' with unique index 'IX_TestEntities_Property'. The duplicate key value is (TestValue).
The statement has been terminated.
Command: INSERT INTO [TestEntities] ([Property]) VALUES ('TestValue')
Inserting row...
```
It *should* emit:
```
Inserting row...
Row inserted with ID = 1.
Inserting row...
Error: Cannot insert duplicate key row in object 'dbo.TestEntities' with unique index 'IX_TestEntities_Property'. The duplicate key value is (TestValue).
The statement has been terminated.
Command: INSERT INTO [TestEntities] ([Property]) VALUES ('TestValue')
Inserting row...
Error: Cannot insert duplicate key row in object 'dbo.TestEntities' with unique index 'IX_TestEntities_Property'. The duplicate key value is (TestValue).
The statement has been terminated.
Command: INSERT INTO [TestEntities] ([Property]) VALUES ('TestValue')
```
The source code of the demo app is well commented, and also shows that if you change from `ExecuteReader` to `ExecuteScalar`, then output is as expected.
Contributor guide
Assessment
This issue has not been assessed yet.