Closed NickCraver closed 4 years ago
@saurabh500 @corivera can you please take a look? This looks like 2.0 blocker. Thanks!
I've pushed up the netstandard2.0
branch of Dapper to GitHub, you can grab it here to run the tests: https://github.com/StackExchange/Dapper/tree/7e5bd308f99b790212e6990bc4ec8b0c72579406
After pulling, you can do a build.cmd -BuildNumber 12345
to run all tests, etc. and see it go boom.
@NickCraver While running the Dapper tests I get the following error:
Run Parameters:
Version:
BuildNumber: 12345
CreatePackages: False
RunTests: True
Base Version: 1.50.3-alpha1-12345
error: /ConsoleLoggerParameters:Verbosity=Quiet
Running tests: Dapper.Tests (all frameworks)
No executable found matching command "dotnet-xunit"
Error with tests, aborting build.
Do you have anything special setup before running build.cmd to setup dotnet-xunit?
@saurabh500 Nothing special, and I just tried it on a fresh VM with only .NET Core 2 installed. Perhaps you have a newer/internal dotnet
in play and need to lower the SDK down to 2 with a global.json
? It seems like it's not loading compatible build-time resources there :-/
@NickCraver After running build.cmd -BuildNumber 12345
, I got all unit test failed with the same error message Dapper.Tests.QueryMultipleTests.SO35554284_QueryMultipleUntilConsumed [FAIL]
Do you have any idea what config I should setup additionally?
D:\Projects\Test\Dapper>build.cmd -BuildNumber 12345
Run Parameters:
Version:
BuildNumber: 12345
CreatePackages: False
RunTests: True
Base Version: 1.50.3-alpha1-12345
Welcome to .NET Core!
---------------------
Learn more about .NET Core @ https://aka.ms/dotnet-docs. Use dotnet --help to see available commands or go to https://aka.ms/dotnet-cli-docs.
Telemetry
--------------
The .NET Core tools collect usage data in order to improve your experience. The data is anonymous and does not include command-line arguments. The data is collected by Microsoft and shared with the community.
You can opt out of telemetry by setting a DOTNET_CLI_TELEMETRY_OPTOUT environment variable to 1 using your favorite shell.
You can read more about .NET Core tools telemetry @ https://aka.ms/dotnet-cli-telemetry.
Configuring...
-------------------
A command is running to initially populate your local package cache, to improve restore speed and enable offline access. This command will take up to a minute to complete and will only happen once.
Decompressing 100% 4727 ms
Expanding 100% 20714 ms
Running tests: Dapper.Tests (all frameworks)
Detecting target frameworks in Dapper.Tests.csproj...
Building for framework net452...
Dapper -> D:\Projects\Test\Dapper\Dapper\bin\Debug\net451\Dapper.dll
Dapper -> D:\Projects\Test\Dapper\Dapper\bin\Debug\net45\Dapper.dll
Dapper.EntityFramework -> D:\Projects\Test\Dapper\Dapper.EntityFramework\bin\Debug\net45\Dapper.EntityFramework.dll
Dapper.Contrib -> D:\Projects\Test\Dapper\Dapper.Contrib\bin\Debug\net45\Dapper.Contrib.dll
Dapper.Tests -> D:\Projects\Test\Dapper\Dapper.Tests\bin\Debug\net452\Dapper.Tests.dll
2 File(s) copied
2 File(s) copied
Running desktop CLR tests for framework net452...
xUnit.net Console Runner (64-bit Desktop .NET 4.0.30319.42000)
Discovering: Dapper.Tests
Dapper: Dapper.SqlMapper, Dapper, Version=1.50.2.0, Culture=neutral, PublicKeyToken=null
Using Connectionstring: Data Source=.;Initial Catalog=tempdb;Integrated Security=True
.NET: 4.0.30319.42000
Loading native assemblies for SQL types...(from: D:\Projects\Test\Dapper\Dapper.Tests\bin\Debug\net452\x64\)...done.
Discovered: Dapper.Tests
Starting: Dapper.Tests
Dapper.Tests.DataReaderTests.DiscriminatedUnionWithMultiMapping [FAIL]
System.Data.SqlClient.SqlException : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
---- System.ComponentModel.Win32Exception : The system cannot find the file specified
Stack Trace:
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
D:\Projects\Test\Dapper\Dapper.Tests\TestBase.cs(35,0): at Dapper.Tests.TestBase.GetOpenConnection(Boolean mars)
D:\Projects\Test\Dapper\Dapper.Tests\TestBase.cs(21,0): at Dapper.Tests.TestBase.get_connection()
D:\Projects\Test\Dapper\Dapper.Tests\DataReaderTests.cs(84,0): at Dapper.Tests.DataReaderTests.DiscriminatedUnionWithMultiMapping()
----- Inner Stack Trace -----
Dapper.Tests.QueryMultipleTests.SO35554284_QueryMultipleUntilConsumed [FAIL]
System.Data.SqlClient.SqlException : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
...
@geleems Dapper assumes a local SQL Server running (since we have to have a database to hit). If you fire one up, it uses your login and runs in tempdb.
@NickCraver Thanks. I ran localdb, and was able to kick off the tests.
But it seems it does not hit the Dapper.Tests.ParameterTests.DataTableParametersWithExtendedProperty()
test. I added Console.WriteLine("*********")
line to see if the test was executed, but it does appear to the console.
Do you have any idea why the test does not run?
D:\Projects\Test\Dapper>build.cmd -BuildNumber 12345
Run Parameters:
Version:
BuildNumber: 12345
CreatePackages: False
RunTests: True
Base Version: 1.50.3-alpha1-12345
Running tests: Dapper.Tests (all frameworks)
Detecting target frameworks in Dapper.Tests.csproj...
Building for framework net452...
Dapper -> D:\Projects\Test\Dapper\Dapper\bin\Debug\net451\Dapper.dll
Dapper -> D:\Projects\Test\Dapper\Dapper\bin\Debug\net45\Dapper.dll
Dapper.Contrib -> D:\Projects\Test\Dapper\Dapper.Contrib\bin\Debug\net45\Dapper.Contrib.dll
Dapper.EntityFramework -> D:\Projects\Test\Dapper\Dapper.EntityFramework\bin\Debug\net45\Dapper.EntityFramework.dll
Dapper.Tests -> D:\Projects\Test\Dapper\Dapper.Tests\bin\Debug\net452\Dapper.Tests.dll
2 File(s) copied
2 File(s) copied
Running desktop CLR tests for framework net452...
xUnit.net Console Runner (64-bit Desktop .NET 4.0.30319.42000)
Discovering: Dapper.Tests
Dapper: Dapper.SqlMapper, Dapper, Version=1.50.2.0, Culture=neutral, PublicKeyToken=null
Using Connectionstring: Data Source=.;Initial Catalog=tempdb;Integrated Security=True
.NET: 4.0.30319.42000
Loading native assemblies for SQL types...(from: D:\Projects\Test\Dapper\Dapper.Tests\bin\Debug\net452\x64\)...done.
Discovered: Dapper.Tests
Starting: Dapper.Tests
Dapper.Tests.Providers.FirebirdTests.Issue178_Firebird [SKIP]
Bug in Firebird; a PR to fix it has been submitted
Dapper.Tests.PostcresqlTests.TestPostgresqlArrayParameters [SKIP]
Postgresql is unavailable: No connection could be made because the target machine actively refused it
Dapper.Tests.SQLCETests.MultiRSSqlCE [FAIL]
System.Data.SqlServerCe.SqlCeException : Unable to load the native components of SQL Server Compact corresponding to the ADO.NET provider of version 8876. Install the correct version of SQL Server Compact. Refer to KB article 974247 for more details.
Stack Trace:
at System.Data.SqlServerCe.NativeMethods.LoadNativeBinaries()
at System.Data.SqlServerCe.SqlCeEngine..ctor()
at System.Data.SqlServerCe.SqlCeEngine..ctor(String connectionString)
D:\Projects\Test\Dapper\Dapper.Tests\Providers\SQLCETests.cs(18,0): at Dapper.Tests.SQLCETests.MultiRSSqlCE()
System.Runtime.Serialization.SerializationException: Unable to find assembly 'System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91'.
at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream stm)
at System.AppDomain.Deserialize(Byte[] blob)
at System.AppDomain.UnmarshalObject(Byte[] blob)
Building for framework netcoreapp1.0...
Dapper -> D:\Projects\Test\Dapper\Dapper\bin\Debug\netstandard1.3\Dapper.dll
Dapper.Contrib -> D:\Projects\Test\Dapper\Dapper.Contrib\bin\Debug\netstandard1.3\Dapper.Contrib.dll
Dapper.Tests -> D:\Projects\Test\Dapper\Dapper.Tests\bin\Debug\netcoreapp1.0\Dapper.Tests.dll
2 File(s) copied
2 File(s) copied
Running .NET Core tests for framework netcoreapp1.0...
xUnit.net Console Runner (64-bit .NET Core 4.6.25009.01)
Discovering: Dapper.Tests
Dapper: Dapper.SqlMapper, Dapper, Version=1.50.2.0, Culture=neutral, PublicKeyToken=null
Using Connectionstring: Data Source=.;Initial Catalog=tempdb;Integrated Security=True
CoreCLR
Discovered: Dapper.Tests
Starting: Dapper.Tests
Dapper.Tests.MiscTests.Issue263_Timeout [SKIP]
Long running
No pipeline: 2265ms
Pipeline: 2759ms
No pipeline: 1627ms
Pipeline: 2327ms
Finished: Dapper.Tests
=== TEST EXECUTION SUMMARY ===
Dapper.Tests Total: 259, Errors: 0, Failed: 0, Skipped: 1, Time: 32.245s
Error with tests, aborting build.
@geleems I only see the netstandard1.3
run - are you sure you're on the netstandard2
branch? It looks like you're testing current master
.
@geleems I could get the tests running
I cloned Dapper and then checked out Nick's commit
git checkout 7e5bd308f99b790212e6990bc4ec8b0c72579406
I uninstalled all the versions of .Net Core. I have .Net Core 2.0 preview 1 installed from https://www.microsoft.com/net/core/preview#windowscmd
I ran the tests and I got an error
Run Parameters:
Version:
BuildNumber: 12345
CreatePackages: False
RunTests: True
Base Version: 1.50.3-alpha1-12345
Running tests: Dapper.Tests (all frameworks)
It was not possible to find any compatible framework version
The specified framework 'Microsoft.NETCore.App', version '1.0.4' was not found.
- Check application dependencies and target a framework version installed at:
\
- Alternatively, install the framework version '1.0.4'.
Error with tests, aborting build.
After this I installed .Net Core Runtime 1.0.5 from https://www.microsoft.com/net/download/core#/runtime.
After this I can execute the tests successfully and I can repro the failures that @NickCraver has reported. The beginning of my Console Output looks like this.
D:\work\Dapper>build.cmd -BuildNumber 12345 -RunTests 1
Run Parameters:
Version:
BuildNumber: 12345
CreatePackages: False
RunTests: True
Base Version: 1.50.3-alpha1-12345
Running tests: Dapper.Tests (all frameworks)
Detecting target frameworks in Dapper.Tests.csproj...
Building for framework net452...
Dapper -> D:\work\Dapper\Dapper\bin\Debug\net451\Dapper.dll
Dapper -> D:\work\Dapper\Dapper\bin\Debug\net45\Dapper.dll
Dapper.EntityFramework -> D:\work\Dapper\Dapper.EntityFramework\bin\Debug\net45\Dapper.EntityFramework.dll
Dapper.Contrib -> D:\work\Dapper\Dapper.Contrib\bin\Debug\net45\Dapper.Contrib.dll
Dapper.Tests -> D:\work\Dapper\Dapper.Tests\bin\Debug\net452\Dapper.Tests.dll
2 File(s) copied
2 File(s) copied
Running desktop CLR tests for framework net452...
xUnit.net Console Runner (64-bit Desktop .NET 4.0.30319.42000)
Discovering: Dapper.Tests
Dapper: Dapper.SqlMapper, Dapper, Version=1.50.2.0, Culture=neutral, PublicKeyToken=null
Using Connectionstring: Data Source=.;Initial Catalog=tempdb;Integrated Security=True
.NET: 4.0.30319.42000
Loading native assemblies for SQL types...(from: D:\work\Dapper\Dapper.Tests\bin\Debug\net452\x64\)...done.
Discovered: Dapper.Tests
Starting: Dapper.Tests
Dapper.Tests.SqliteTests.DapperEnumValue_Sqlite [SKIP]
Sqlite is unavailable: Unable to load DLL 'sqlite3': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Dapper.Tests.SqliteTests.Issue466_SqliteHatesOptimizations_Async [SKIP]
Sqlite is unavailable: Unable to load DLL 'sqlite3': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Dapper.Tests.SqliteTests.Isse467_SqliteLikesParametersWithPrefix [SKIP]
Sqlite is unavailable: Unable to load DLL 'sqlite3': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Dapper.Tests.SqliteTests.Issue466_SqliteHatesOptimizations [SKIP]
Sqlite is unavailable: Unable to load DLL 'sqlite3': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Dapper.Tests.SqliteTests.Isse467_SqliteLikesParametersWithoutPrefix [SKIP]
Sqlite is unavailable: Unable to load DLL 'sqlite3': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Dapper.Tests.PostcresqlTests.TestPostgresqlArrayParameters [SKIP]
Postgresql is unavailable: No connection could be made because the target machine actively refused it
Dapper.Tests.MySQLTests.Issue295_NullableDateTime_MySql_Default [SKIP]
MySql is unavailable: Unable to connect to any of the specified MySQL hosts.
Dapper.Tests.MySQLTests.Issue426_SO34439033_DateTimeGainsTicks [SKIP]
MySql is unavailable: Unable to connect to any of the specified MySQL hosts.
Dapper.Tests.MySQLTests.SO36303462_Tinyint_Bools [SKIP]
MySql is unavailable: Unable to connect to any of the specified MySQL hosts.
Dapper.Tests.MySQLTests.Issue295_NullableDateTime_MySql_ConvertZeroDatetime [SKIP]
MySql is unavailable: Unable to connect to any of the specified MySQL hosts.
Dapper.Tests.MySQLTests.Issue552_SignedUnsignedBooleans [SKIP]
MySql is unavailable: Unable to connect to any of the specified MySQL hosts.
Dapper.Tests.MySQLTests.Issue295_NullableDateTime_MySql_ConvertAllowZeroDatetime [SKIP]
MySql is unavailable: Unable to connect to any of the specified MySQL hosts.
Dapper.Tests.MySQLTests.Issue295_NullableDateTime_MySql_AllowZeroDatetime [SKIP]
MySql is unavailable: Unable to connect to any of the specified MySQL hosts.
I have a repro with SqlClient code, I extracted this from Dapper
public static void TestParametersWithTVP()
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = "localhost";
builder.IntegratedSecurity = true;
builder.InitialCatalog = "tempdb";
var table = new DataTable { Columns = { { "id", typeof(int) } }, Rows = { { 1 }, { 2 }, { 3 } } };
table.ExtendedProperties["dapper:TypeName"] = "MyTVPType";
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
connection.Open();
using (SqlCommand cmd = connection.CreateCommand())
{
try { cmd.CommandText = "drop proc #DataTableParameters"; cmd.ExecuteNonQuery(); }
catch { /* Dont Care about exception */ }
}
using (SqlCommand cmd = connection.CreateCommand())
{
try { cmd.CommandText = "drop table #DataTableParameters"; cmd.ExecuteNonQuery(); }
catch { /* Dont Care about exception */ }
}
using (SqlCommand cmd = connection.CreateCommand())
{
try { cmd.CommandText = "drop type MyTVPType"; cmd.ExecuteNonQuery(); }
catch { /* Dont Care about exception */ }
}
using (SqlCommand cmd = connection.CreateCommand())
{
try { cmd.CommandText = "create type MyTVPType as table (id int)"; cmd.ExecuteNonQuery(); }
catch { /* Dont Care about exception */ }
}
using (SqlCommand cmd = connection.CreateCommand())
{
try { cmd.CommandText = "create proc #DataTableParameters @ids MyTVPType readonly as select count(1) from @ids"; cmd.ExecuteNonQuery(); }
catch { /* Dont Care about exception */ }
}
using (SqlCommand cmd = connection.CreateCommand())
{
cmd.CommandText = "#DataTableParameters";
SqlParameter parameter = cmd.Parameters.AddWithValue("@ids", table);
parameter.TypeName = "MyTVPType";
using (SqlDataReader reader = cmd.ExecuteReader())
{
while(reader.HasRows) { reader.NextResult(); }
}
}
}
}
What this repro highlights is that SqlClient Parameters don't support TVPs. Looking into this.
I was able to port the code for TVPs using DataTables in SqlParameters and after running the Dapper tests using my changes I could see 100% pass rate in Dapper.Tests
Finished: Dapper.Tests
=== TEST EXECUTION SUMMARY ===
Dapper.Tests Total: 274, Errors: 0, Failed: 0, Skipped: 13, Time: 37.300s
Building for framework netcoreapp2.0...
Dapper -> D:\work\Dapper\Dapper\bin\Debug\netstandard2.0\Dapper.dll
Dapper -> D:\work\Dapper\Dapper\bin\Debug\netstandard1.3\Dapper.dll
Dapper.Contrib -> D:\work\Dapper\Dapper.Contrib\bin\Debug\netstandard1.3\Dapper.Contrib.dll
Dapper.Tests -> D:\work\Dapper\Dapper.Tests\bin\Debug\netcoreapp2.0\Dapper.Tests.dll
2 File(s) copied
2 File(s) copied
...
Running .NET Core tests for framework netcoreapp2.0...
xUnit.net Console Runner (64-bit .NET Core 4.6.25302.01)
Discovering: Dapper.Tests.Contrib
Discovered: Dapper.Tests.Contrib
Starting: Dapper.Tests.Contrib
Dapper.Tests.Contrib.SqlServerTestSuite.TransactionScope [FAIL]
Assert.Null() Failure
Expected: (null)
Actual: Car { Computed = null, Id = 5, Name = "one car" }
Stack Trace:
D:\work\Dapper\Dapper.Tests\Helpers\Assert.cs(44,0): at Dapper.Tests.Assert.IsNull(Object obj)
D:\work\Dapper\Dapper.Tests.Contrib\TestSuite.cs(542,0): at Dapper.Tests.Contrib.TestSuite.TransactionScope()
Dapper.Tests.Contrib.SQLiteTestSuite.TransactionScope [FAIL]
Assert.Null() Failure
Expected: (null)
Actual: Car { Computed = null, Id = 5, Name = "one car" }
Stack Trace:
D:\work\Dapper\Dapper.Tests\Helpers\Assert.cs(44,0): at Dapper.Tests.Assert.IsNull(Object obj)
D:\work\Dapper\Dapper.Tests.Contrib\TestSuite.cs(542,0): at Dapper.Tests.Contrib.TestSuite.TransactionScope()
@NickCraver I do see a couple failures in Dapper.Tests.Contrib
listed above.
One of them is Dapper.Tests.Contrib.SqlServerTestSuite.TransactionScope
It looks like the test is expecting to use TransactionScope with SqlClient. SqlClient doesn't support TransactionScope. We had to move the feature out of .Net 2.0 due to lack time and this is quite a bit of an involved feature https://github.com/dotnet/corefx/issues/12534
@saurabh500 how can customers detect the missing feature? Is it runtime failure? Or compile time / missing API failure? If it is runtime failure, I'd be curious how blocking it is for which scenarios? (@NickCraver? @FransBouma? @cincuranet?) At minimum, we need to document the difference in ApPiCompat, so that Immo's tooling flags it to people ...
@karelz I think you are referring to my comment
It looks like the test is expecting to use TransactionScope with SqlClient. SqlClient doesn't support TransactionScope. We had to move the feature out of .Net 2.0 due to lack time and this is quite a bit of an involved feature dotnet/runtime#18918
This will lead to runtime anomaly in behavior. If one expects SqlClient command executions to be wrapped in a Single TransactionScope
and a transaction executed in the scope, then the customers would find out that the TransactionScope transaction enlistment is not supported. This will be profound in failure cases, where the operations in TransactionScope
are not really considered a part of a single transaction.
With TransactionScope support in SqlClient, we will not be able to get to the complete Desktop behavior, because only Local transactions are supported in Sys.Transactions and Distributed transactions across different Sql Servers will not be supported due to the current limitations of Sys.Transactions.
What will the customer see? Exception? Or just "wrong non-transactional behavior"?
No exceptions. They will see non-transactional behavior
How bad and surprising is it? Can we flag specific method, field, enum value or something in the ApiCompat tool?
IMHO, if the user uses TransactionScope in the code, they'll assume it will work if there are no compile errors. If the user gets a runtime exception, it will be frustrating perhaps for the user, but at least they won't assume the work is performed using a single transaction. If things are silently done without transactional behavior it can be seriously bad if they have to rollback due to an error and the code won't roll back, resulting in an inconsistent database.
I have opened an issue https://github.com/dotnet/corefx/issues/19894 to discuss this behavior.
I agree with @FransBouma . In case all the operations in a TransactionScope go well, then there would be no customer complains, but if one of the operations fail, the the application would expect all the operations in TransactionScope to be rolled back. This is bad for data integrity. The failure case is where Sys.Transactions are most important for. This can be bad for customers who are migrating existing applications.
Reopening to track port to rel/2.0.0 branch
If I can chime in, I think the ongoing lack of support for TransactionScope in SqlClient is going to make it difficult to embrace .NET Core. The usual suggestion for creating connections is that you create and open them as late as possible, then dispose of them as soon as possible, meaning that for a given business process, the work of writing to the database may very well be split across multiple connections. As I understand it, if TransactionScope is not available, the only option is to create a transaction from an existing connection, which leaves no simple way to guarantee transactional behavior when a process requires multiple writes to a database -- which in my case, and I would imagine for a lot of others, happens quite frequently. For my application, the only clear workaround -- using the same connection for multiple commands -- would force connection and transaction management up into the domain layer, increasing complexity and adding extra responsibilities. In other words, the lack of support for TransactionScope seems to make less-than-desirable design choices inevitable. I'm certainly not on expert on this subject, so I would definitely welcome any insight on this problem. There's more about my particular situation here: https://stackoverflow.com/questions/44163915/net-core-transaction-decorator-without-transactionscope
@moleculomjd thanks for you information. Definitely valuable view point. @saurabh500 do we have TransactionScope issue tracking the future work? I would love to move the discussion there. If it is important, we should find a way to fund it across teams rather sooner than later. Thanks!
cc @divega
@moleculomjd ambient transactions aren't always a plus, as they create some overhead, and not every database supports them on the server side (afaik, only sqlserver does, and Oracle over MTS/COM+ with a separate service). An alternative can be to use a unit of work which collects the activity you have to perform for the business process, and then performs the actions quickly in a single ado.net transaction. Some ORMs supply a Unit of work class which is separated from persistence logic (EF does not btw). It isn't always a good alternative (e.g. when the business process is long with a lot of back/forth activity), but for multiple save actions in a pipeline of calls it might be.
@karelz @moleculomjd @FransBouma TransactionScope
support in SqlClient is covered by an issue @saurabh500 mentioned before in this thread: https://github.com/dotnet/corefx/issues/12534. Makes sense to start any discussion about the details of what it means for SqlClient there.
Any discussion about inherent limitations of System.Transactions
in .NET Core (e.g. lack of distributed transaction support) ideally should go in a separate issue.
@NickCraver I am also facing the same issue object must implement iconvertible after upgrading .net core 2.2 to 3.1 but with Efcore and ado.net
I'm not sure if there are other issues beyond this, but hitting the first boom with SQL TVPs (table valued parameters) when attempting to restore support in Dapper with
netstandard2.0
.In the reference source for
SqlParameter.CoerceValue()
, there's an explicit check to not attempt conversion on aDataTable
:Compared to the code in CoreFX:
Without this match, it falls down below resulting in:
This may be a single backporting oversight, or there may be deeper issues with
DataTable
as a parameter beyond this. Filing because this is the wall I'm hitting at the moment.