Conversion issues moving from VS 2005 to VS 2008
Published Jan 15 2019 01:48 PM 333 Views
Microsoft
First published on MSDN on Apr 21, 2011

I was asked to look at a case yesterday where the customer was hitting the following error after converting a VS 2005 Project to VS 2008.

Error 3 Custom tool error: Failed to generate code. Failed to generate code. Exception of type 'System.Data.Design.InternalException' was thrown. Exception of type 'System.Data.Design.InternalException' was thrown.

This was being produce by an XSD file which was a DataSet based on SQL CE.  Luckily I could reproduce the issue locally with the customer’s project which made digging into this much easier.

Unfortunately, the error displayed above didn’t really give me a lot to go on, but it was an exception so I could get a memory dump.  The thing I love about Managed (.NET) code is that customers can pretty much do the same thing and don’t necessarily need internal symbols.  The Debugging Tools ship with an extension called SOS which you can load to look at things like the Managed Call Stack, and different objects.  To get the dump, you can go about it different ways.  One way would be to use a tool called DebugDiag (available from the Microsoft Download Center) and setup a rule for getting First Chance Exceptions on CLR exceptions. I actually just did a live debug within WinDBG as it was quicker for me to go through that.  I had to sift through a bunch of exceptions until I arrived at the InternalException.  Here was the call stack for the exception (which wasn’t presented in Visual Studio:

0:000> !clrstack
OS Thread Id: 0x32cc (0)
ESP       EIP
002a949c 7614b727 [HelperMethodFrame: 002a949c]
002a9540 6a42ce4a System.Data.Design.ProviderManager.GetFactory(System.String)
002a9568 6a10c881 System.Data.Design.DataComponentMethodGenerator..ctor(System.Data.Design.TypedDataSourceCodeGenerator, System.Data.Design.DesignTable, Boolean)
002a9580 6a10c586 System.Data.Design.DataComponentGenerator.GenerateDataComponent(System.Data.Design.DesignTable, Boolean, Boolean)
002a95ec 6a116e0e System.Data.Design.TypedDataSourceCodeGenerator.GenerateDataSource(System.Data.Design.DesignDataSource, System.CodeDom.CodeCompileUnit, System.CodeDom.CodeNamespace, System.String, GenerateOption)
002a9650 6a140372 System.Data.Design.TypedDataSetGenerator.GenerateInternal(System.Data.Design.DesignDataSource, System.CodeDom.CodeCompileUnit, System.CodeDom.CodeNamespace, System.CodeDom.Compiler.CodeDomProvider, GenerateOption, System.String)
002a96a0 6a14061c System.Data.Design.TypedDataSetGenerator.Generate(System.String, System.CodeDom.CodeCompileUnit, System.CodeDom.CodeNamespace, System.CodeDom.Compiler.CodeDomProvider, GenerateOption, System.String)
002a96d8 6a1406bb System.Data.Design.TypedDataSetGenerator.Generate(System.String, System.CodeDom.CodeCompileUnit, System.CodeDom.CodeNamespace, System.CodeDom.Compiler.CodeDomProvider, System.Collections.Hashtable, GenerateOption, System.String)
002a9714 6a14071f System.Data.Design.TypedDataSetGenerator.Generate(System.String, System.CodeDom.CodeCompileUnit, System.CodeDom.CodeNamespace, System.CodeDom.Compiler.CodeDomProvider, System.Collections.Hashtable, GenerateOption)

That alone tells me a lot.  It looks like we are trying to load a provider and some error is occurring.  Our InternalException.  InternalException still doesn’t tell me what the failure was, but the fact that we are trying to load a Provider narrows the window.  Either we failed to find the provider, or it failed to load assuming we aren’t doing some processing within the GetFactory call itself.

Using .NET Reflector, you can have a look at System.Data.Design.ProviderManager.GetFactory to see what is inside it.  What we are looking for are where we actually throw InternalException.  I saw two places where that happens:

throw new InternalException( string.Format(System.Globalization.CultureInfo.CurrentCulture, "Cannot find provider factory for provider named {0}", invariantName) );

throw new InternalException( string.Format(System.Globalization.CultureInfo.CurrentCulture, "More that one data row for provider named {0}", invariantName) );

Based on this, it was either missing, or there were multiple entries for the provider.  But, what provider?  One thing I know based on the case itself is that it is SQL CE related, so probably a CE Provider. At that point, I typically look at the managed stack to see if I can figure out what that invariantName value is.

0:000> !dso
OS Thread Id: 0x32cc (0)
ESP/REG  Object   Name
002a9430 1776c3bc System.Data.Design.InternalException
002a9440 07f6a388 System.Resources.ResourceReader
002a947c 1776c3bc System.Data.Design.InternalException
002a948c 081902d8 System.String    Microsoft.SqlServerCe.Client
002a9490 1776c3bc System.Data.Design.InternalException
002a9494 1776c3a8 System.Object[]    (System.Object[])
002a94bc 07a71c3c System.String    en-US
002a94c0 1776c3bc System.Data.Design.InternalException
002a94c8 1776c3bc System.Data.Design.InternalException
002a94cc 07a71ccc System.String    en-US
002a94d0 1776c3a8 System.Object[]    (System.Object[])
002a94d8 07a9aabc System.Globalization.CompareInfo
002a94dc 07f6a1e0 System.Resources.ResourceManager
002a94f4 1776c698 System.String    ERR_INTERNAL
002a94f8 1776c3a8 System.Object[]    (System.Object[])
002a94fc 1776c698 System.String    ERR_INTERNAL
002a951c 1776c3bc System.Data.Design.InternalException
002a9524 1776c3bc System.Data.Design.InternalException <- This is where the Exception was thrown
002a9540 07a71b18 System.Globalization.CultureInfo
002a9548 07a71b18 System.Globalization.CultureInfo
002a954c 1776b5fc System.Object[]    (System.Object[])
002a9550 081c6038 System.Data.Design.DesignTable

We can see the Exception, and one of the strings listed is “Microsoft.SqlServerCe.Client”, but it is listed after the Exception was thrown. I could go with that, but I do see an Object Array right before the Exception.  Lets have a look at that to see what is in it.  It may be related.

0:000> !DumpArray 1776b5fc <- could use !da also
Name: System.Object[]
MethodTable: 60ec42b8
EEClass: 60cada64
Size: 20(0x14) bytes
Array: Rank 1, Number of elements 1, Type CLASS
Element Methodtable: 60ef0704
[0] 081902d8

0:000> !do 081902d8
Name: System.String
MethodTable: 60ef0ae8
EEClass: 60cad65c
Size: 74(0x4a) bytes
(C:WindowsassemblyGAC_32mscorlib2.0.0.0__b77a5c561934e089mscorlib.dll)
String: Microsoft.SqlServerCe.Client

That looks pretty good to me.  Lets go with “Microsoft.SqlServerCe.Client”.  I started off by doing just a quick Bing search on it.  And I got the following Forum post:

http://social.msdn.microsoft.com/Forums/en-US/vside2008/thread/4b3a423f-1bcb-4a3c-b582-fd3a1f3b...

which lead me to the following forum post:

http://social.msdn.microsoft.com/forums/en-US/sqlce/thread/09ac8a71-a96d-4af2-8a19-43258b6ca7be...

Which based on that, led me to my Machine.Config. In the case of my machine, I do not have a provider listed for “Microsoft.SqlServerCe.Client” within my Machine.Config at C:windowsMicrosoft.NETFrameworkv2.0.50727CONFIG. I have the following:

<system.data>

<DbProviderFactories>

<add name="Odbc Data Provider" invariant="System.Data.Odbc" description=".Net Framework Data Provider for Odbc" type="System.Data.Odbc.OdbcFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

<add name="OleDb Data Provider" invariant="System.Data.OleDb" description=".Net Framework Data Provider for OleDb" type="System.Data.OleDb.OleDbFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

<add name="OracleClient Data Provider" invariant="System.Data.OracleClient" description=".Net Framework Data Provider for Oracle" type="System.Data.OracleClient.OracleClientFactory, System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

<add name="SqlClient Data Provider" invariant="System.Data.SqlClient" description=".Net Framework Data Provider for SqlServer" type="System.Data.SqlClient.SqlClientFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

<add name="Microsoft SQL Server Compact Data Provider" invariant="System.Data.SqlServerCe.3.5" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=3.5.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />

<add name="SQL Server Compact Edition Data Provider" invariant="System.Data.SqlServerCe" description=".NET Framework Data Provider for Microsoft SQL Server Compact Edition" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />

</DbProviderFactories>

</system.data>

The entry that it is looking for is the following, based on the second forum post.

<add name="SQL Server CE Data Provider" invariant="Microsoft.SqlServerCe.Client" description=".NET Framework Data Provider for Microsoft SQL Server 2005 Mobile Edition" type="Microsoft.SqlServerCe.Client.SqlCeClientFactory, Microsoft.SqlServerCe.Client, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />

However, I don’t have that assembly on my machine. I believe this comes from the VS 2005 binaries and I don’t have VS 2005 installed on my machine. The reason the InternalException is being triggered is due to the following line within the XSD:

<Connection ConnectionStringObject="Data Source =&quot;.mydatabase.sdf&quot;" IsAppSettingsProperty="False" Modifier="Assembly" Name="MyConnectionString" ParameterPrefix="@" Provider="Microsoft.SqlServerCe.Client">

</Connection>

Before opening the 2005 Project in VS 2008, I modified that line within the XSD from “Microsoft.SqlServerCe.Client” to “System.Data.SqlServerCe”. After that, I opened the project in VS 2008 and did not receive the error. It appears to have used a valid provider at that point which allowed the conversion to proceed.

Adam W. Saxton | Microsoft SQL Server Escalation Services
https://twitter.com/awsaxton


Version history
Last update:
‎Jan 15 2019 01:48 PM
Updated by: