-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
SqliteDataReader.Read throws "Invalid attempt to call Read when reader is closed." #24015
Comments
@ryepup I don't think there's any explicit contract somewhere saying that a reader must outlive its command - even if that's the SqlClient behavior. In fact, since a reader is obtained from a command (i.e. by executing it), there's some sense in the reader not working beyond the scope of the command's lifecycle; just like the reader is invalidated once its connection is closed/disposed. On the flip side, compatbility with the SqlClient behavior is definitely a plus (Npgsql also allows leaves the reader working after command disposal). |
@roji true, but there's also no contract saying that the command's lifecycle and the reader's lifecycle are related. From
I interpret that to mean the command has done it's job, and the rest is between the C# doesn't give us many tools to express this kind of issue, best I can think of is either:
|
Yep. ADO.NET is a notoriously ambiguous spec. I do agree with you that given that SqlClient and Npgsql allow it, it's probably preferable for Sqlite to also allow it - unless there's some specific implementation issue there. |
Note from triage: the behavior of SQLite here will change based on the implementation of #14044. This should allow disposing of the command before disposing of the data reader. (Note that some providers don't require that the DbCommand be disposed. However, in general ADO.NET requires that DbCommand be disposed. We are not changing this, even though SQLite may join those providers that do not need it.) |
Bumped into this issue trying to migrate to Microsoft.Data.Sqlite. Our application allows the use of either MySQL, SQL Server, Oracle, or Mono.Data.Sqlite for many years and none of these providers have a problem with IDataReader outliving the command. Any plans to get this fixed? |
This issue is in the Backlog milestone. This means that it is not planned for the next release (EF Core 8.0). We will re-assess the backlog following the this release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources. Make sure to vote (👍) for this issue if it is important to you. |
@roji - Appreciate the fast response. FYI, our use case is a bit different from the original reporter. We're attempting to use the library directly, outside of ef, on Android devices as part of migrating away from Xamarin to NET8. |
I'm using sqlite in-memory databases as a lightweight way to test code that will normally talk to Sql Server.
I'm writing some code that expects to deal with large result sets and stream data from the database without holding the entire dataset in memory. That code is written in terms of
IDbConnection
.I'm running into unexpected errors where my test works with a
SqlConnection
, but fails with aSqliteConnection
.The code I'm testing has a few layers, but the error can be reproduced with only
Microsoft.Data.Sqlite
.Reproduction case
Install Microsoft.Data.Sqlite, run this mstest:
Expected behavior
The test passes, and disposing the
IDbCommand
has no effect on theIDataReader
.Actual behavior
Test fails:
Any attempts to call
reader.Read()
throw:Analysis
If you replace my
new SqliteConnection("Data Source=:memory:")
with anew SqlConnection
pointing towards a read SQL server, the test passes.I think the difference in behavior comes from
SqliteCommand
vsSqlCommand
.SqliteCommand
holds a reference to any data readers it opens:efcore/src/Microsoft.Data.Sqlite.Core/SqliteCommand.cs
Line 315 in ea79edc
When
SqliteCommand.Dispose
is called, any related reader is also disposed:efcore/src/Microsoft.Data.Sqlite.Core/SqliteCommand.cs
Line 522 in ea79edc
SqlCommand
does not keep references to its readers nor attempt to clean them up; those are the caller's responsibility.I think this behavior makes
SqliteCommand
go beyond the contract ofIDbCommand.ExecuteReader
.Versions
Microsoft.Data.Sqlite version: 5.0.2 and 3.1.11
Target framework: netcoreapp3.1
Operating system: ubuntu20.04 under WSL2 under win10
The text was updated successfully, but these errors were encountered: