Linqpad6 loads same assembly twice, leading to type1 != type1 issues
Trying to migrate driver to linqpad6 and have issue with same assembly loaded twice, which leads to errors with reflection code. See attached screen.
Same System.Data.Common.dll loaded twice (same name, version, path) with second load right after dirver assembly.
We don't load this assembly explicitly and I don't even have time to intercept load - it is already loaded second time in driver class static constructor.
Any ideas/suggestions what's going on and how to fix it?
Comments
-
Can you post the .csproj file for your driver?
-
Or if you're able, can you check your driver into a public repository so I can take a look at the whole thing?
-
Sure. Just create firebird or access oledb connection and try to expand db node (no real connection string required as it fails earlier).
E.g. access
or firebird -
access ODBC provider works, as it doesn't use failing funtionality
-
Source code : https://github.com/linq2db/linq2db.LINQPad/pull/32
just build project and it will generate lpx files in project root -
OK, I've got the project and modified the .csproj so that it copies the output to a folder where LINQPad can load it:
<Target Name="PostBuild1" AfterTargets="PostBuildEvent" Condition="'$(TargetFramework)' == 'netcoreapp3.0'"> <Exec Command="$(ProjectDir)Pack.bat $(TargetDir) lpx6" /> <Exec Command="$(ProjectDir)DevDeploy6.bat $(TargetDir)" /> </Target>
and added DevDeploy6.bat:
xcopy /i/y/s %1*.dll "%LOCALAPPDATA%\LINQPad\Drivers\DataContext\netcore\linq2db.LINQPad\*.*" xcopy /i/y/s %1*.pdb "%LOCALAPPDATA%\LINQPad\Drivers\DataContext\netcore\linq2db.LINQPad\*.*" xcopy /i/y *.png "%LOCALAPPDATA%\LINQPad\Drivers\DataContext\netcore\linq2db.LINQPad\*.*"
It now builds and I can use the driver in LINQPad. I've chosen 'Firebird' as the database driver. What should I type into the connection string box to reproduce the error?
-
It actually doesn't matter, as it fails before connection string used, but format is like
DataSource=localhost;Database=TESTDB25.FDB;User Id=SYSDBA;Password=masterkey -
Remove this line from your GetAssembliesToAdd method:
yield return typeof(IDbConnection).Assembly.Location;
The IDbConnection type is part of the .NET Core Framework which is automatically referenced. If you reference it again, it will assume it's a non-core assembly and will resolve it to the user ALC.
-
Whoops... sorry for that. Now I'm getting
will check what else wrong -
Sounds like you're trying to compile without the whole FX. This is what I do in the EF Core driver:
var resolvedPaths = DataContextDriver.ResolveReferences (cxInfo).CompilationAssemblyPaths; string[] refPaths = DataContextDriver.GetCoreFxReferenceAssemblies ().Union (resolvedPaths).ToArray(); var result = DataContextDriver.CompileSource (new CompilationInput { SourceCode = new[] { dcSource, entitiesSource, CompatibilityExtensionClassSource }, FilePathsToReference = refPaths, OutputPath = name.CodeBase });
-
Thanks! Now it's working!
-
Terrific. Let me know when you upload the driver to NuGet and I'll add it to the 'featured' tab.
-
Released: https://www.nuget.org/packages/linq2db.LINQPad / https://github.com/linq2db/linq2db.LINQPad/releases/tag/v3.0.0 (release notes link in nuget borken, will be fixed in next version)
BTW, I have one suggestion and question:
- it makes sense to add information to DataContextDrivers6.docx about location of Connection.png and FailedConnection.png files. I tried several places and found that they should go to lib/netcoreapp3.0 folder alongside with driver dll. I've checked several other drivers on nuget and they put them incorrectly to content or contentFiles folder
- for a long time we have workaround for SqlHierarchyId type in PreprocessObjectToWrite method: https://github.com/linq2db/linq2db.LINQPad/blob/master/Source/XmlFormatter.cs#L412. I don't know what so special about this type, but for other types when we return RawHtml(XElement) LINQPad call PreprocessObjectToWrite second time with XElement value, but not for this type (so as workaround we return unformatted string for it to work). I assume it is type-related, as it doesn't work even with fake RawHtml(XElement) which works for other types. SqlHierarchyId could be found here https://www.nuget.org/packages/Microsoft.SqlServer.Types/ or here https://www.nuget.org/packages/dotMorten.Microsoft.SqlServer.Types/