Why did my Visual Studio 10 stop using App.Config for my SQL connection string? - sql-server

I have a working database application using WPF and SQL Server 2008 R2, which for two years has been getting its SQL Server connection string from the App.Config file. A few days ago on one dev machine, it started ignoring the App.Config file's connectionString, and is now using a string from somewhere else (looks like either settings.settings, or the DBML file).
Why might this be happening, and how can I get it to stop doing that?
The app.config starts out like this:
<configuration>
<configSections>
<section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
</configSections>
<connectionStrings>
<add name="DronzApp.Properties.Settings.DronzAppConnectionString"
connectionString="Server=dronz.db.123.dronzdbserver.com;Database=dronzdb;User ID=dronz;Password=secretsauce;"
providerName="System.Data.SqlClient" />
</connectionStrings>
Edit: Thanks for the suggestions from both of you for more info and where to look. I don't know where a WPF App gets the information that it ought to look in App.Config, or anyplace else, but until I learn that, here are some more pieces:
One of the first things my program does is test the database (which now fails). Right before it does that, it calls the auto-generated function InitializeComponent(), whose auto-generated code is:
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void InitializeComponent() {
if (_contentLoaded) {
return;
}
_contentLoaded = true;
System.Uri resourceLocater = new System.Uri("/DronzApp;component/ui/startwindow.xaml", System.UriKind.Relative);
#line 1 "..\..\..\UI\StartWindow.xaml"
System.Windows.Application.LoadComponent(this, resourceLocater);
#line default
#line hidden
}
My start window constructor calls InitializeComponent(); and then tests the database with the line:
int hmm = App.db.Dronz_FooTable.Count();
where App.db is a data context defined in the app.xaml.cs file as:
public static DronzDataDataContext db = new DronzDataDataContext();
where DronzDataDataContext is defined in auto-generated code by LINQ-to-SQL such as:
public partial class DronzDataDataContext : System.Data.Linq.DataContext
...
public DronzDataDataContext() :
base(global::DronzApp.Properties.Settings.Default.DronzConnectionString, mappingSource)
{
OnCreated();
}
Which used to heed the app.config file, and now doesn't. When I catch the DB exception (which is about a DB version problem because it is trying to use the wrong SQL server) and look at the connection string, it is asking the wrong SQL Server for a file instead of the correct connection string. The connection string it is using seems to match either the DBML file that Linq-to=SQL created when the database schema was imported, or a string in settings.settings (which is a file I don't really understand where it came from or what I'm supposed to do or not do with it).

Ok, I seem to have found and fixed the problem, but I don't know what caused it, exactly.
What references the Config file is actually in the .proj file, and somehow it changed to add a reference to app.config at the project root instead of in an App subfolder. From reading other discussion of app.config, I think VS2010 did this automatically perhaps when I was looking at the Project settings in the GUI. Deleting that line of XML manually from the .proj file allowed it to find and use the previous version which points to where the app.config file actually is. Since I didn't have an app.config file in the project root where the new first line was edited to say it was in the .proj file, it seems to have fallen to looking at settings.settings, where it found the connectionString value where the file was when I imported the database file using Linq to SQL.

Related

msadox28.tlb is not a valid .Net assembly file while registering it

I am developing application with vb.net (2015) and MS Access database. I can work fine with existing database. I have now situation where I need to create database programmatically, for billing purpose. It is the situation where each folder will contain database for company/firm selection.
After searching on the internet / StackOverflow I learned about ADOX. Even got the ready code for it. I applied it in my coding.
Adding reference of Microsoft ADO extend 2.8 and 6.0
Created variable Adx as new Adox.catalog
Then finally wrote Adx.create(olejet provider conn string with data source)
In this step I get an error
COM Class not registered
So I tried to register msadox.dll and msadox28.tlb with regsvr32 and regasm but at that time I get another error:
msadox.dll get registered successfully but error gives in msadox28.tlb
Fail to load -file- becuase it is not a valid .net assembly file
Now I am stuck at this point.
My system is Windows 10 64 bit. I tried to target cpu x86, and any cpu but it didn't work. I got many questions and answer here but didn't understand it.
EDIT:
I tried following connection string and it worked, but it creates old 2000-2003 mdb file. i want to use new access file .accdb
String is :
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\VBProj\Testing\test.mdb;Jet OLEDB:Engine Type=5
EDIT : on 20/9/2021 - MON
First of all Thank you very much #Jimi, your suggestion to use ACE.16 and cleaning solution worked. Thanks a lot
I use the following steps to create MS Access database using ADOX in VB.NET:
Project Menu > Add Reference > COM Section > Select Microsoft ADO Ext. 6.0 for DLL and security
Write connection string at program entry point (form load/sub main) -> Provider=Microsoft.ACE.OLEDB.16.0;Data Source=D:\VBProj\Testing\test.accdb, assign it to variable connString
Declare adox catalog globally like Public gAdxCat As New ADOX.Catalog
Use its method gAdxCat.create(connString)
That's all - DONE
Again thanks to #jimi
This is the answer to my question (helped by #jimi)
following are the steps to create msaccess database using ADOX in VB.NET and error occurs mention in original questions.
1-Project Menu > Add Reference > COM Section > Select Microsoft ADO Ext. 6.0 for DLL and security (remove ref of 2.8)
2-write connection string at program entry point (form load/sub main) -> "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=D:\VBProj\Testing\test.accdb" assign it to variable connString
3-declare adox catalog globally like Public gAdxCat As New ADOX.Catalog
4-User its method gAdxCat.create(connString)
5-Thats all DONE
again thanks to #jimi

Windows Forms save to dataset but not table [duplicate]

I have following C# code in a console application.
Whenever I debug the application and run the query1 (which inserts a new value into the database) and then run query2 (which displays all the entries in the database), I can see the new entry I inserted clearly. However, when I close the application and check the table in the database (in Visual Studio), it is gone. I have no idea why it is not saving.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlServerCe;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
string fileName = "FlowerShop.sdf";
string fileLocation = "|DataDirectory|\\";
DatabaseAccess dbAccess = new DatabaseAccess();
dbAccess.Connect(fileName, fileLocation);
Console.WriteLine("Connected to the following database:\n"+fileLocation + fileName+"\n");
string query = "Insert into Products(Name, UnitPrice, UnitsInStock) values('NewItem', 500, 90)";
string res = dbAccess.ExecuteQuery(query);
Console.WriteLine(res);
string query2 = "Select * from Products";
string res2 = dbAccess.QueryData(query2);
Console.WriteLine(res2);
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e);
Console.ReadLine();
}
}
}
class DatabaseAccess
{
private SqlCeConnection _connection;
public void Connect(string fileName, string fileLocation)
{
Connect(#"Data Source=" + fileLocation + fileName);
}
public void Connect(string connectionString)
{
_connection = new SqlCeConnection(connectionString);
}
public string QueryData(string query)
{
_connection.Open();
using (SqlCeDataAdapter da = new SqlCeDataAdapter(query, _connection))
using (DataSet ds = new DataSet("Data Set"))
{
da.Fill(ds);
_connection.Close();
return ds.Tables[0].ToReadableString(); // a extension method I created
}
}
public string ExecuteQuery(string query)
{
_connection.Open();
using (SqlCeCommand c = new SqlCeCommand(query, _connection))
{
int r = c.ExecuteNonQuery();
_connection.Close();
return r.ToString();
}
}
}
EDIT: Forgot to mention that I am using SQL Server Compact Edition 4 and VS2012 Express.
It is a quite common problem. You use the |DataDirectory| substitution string. This means that, while debugging your app in the Visual Studio environment, the database used by your application is located in the subfolder BIN\DEBUG folder (or x86 variant) of your project. And this works well as you don't have any kind of error connecting to the database and making update operations.
But then, you exit the debug session and you look at your database through the Visual Studio Server Explorer (or any other suitable tool). This window has a different connection string (probably pointing to the copy of your database in the project folder). You search your tables and you don't see the changes.
Then the problem get worse. You restart VS to go hunting for the bug in your app, but you have your database file listed between your project files and the property Copy to Output directory is set to Copy Always. At this point Visual Studio obliges and copies the original database file from the project folder to the output folder (BIN\DEBUG) and thus your previous changes are lost.
Now, your application inserts/updates again the target table, you again can't find any error in your code and restart the loop again until you decide to post or search on StackOverflow.
You could stop this problem by clicking on the database file listed in your Solution Explorer and changing the property Copy To Output Directory to Copy If Newer or Never Copy. Also you could update your connectionstring in the Server Explorer to look at the working copy of your database or create a second connection. The first one still points to the database in the project folder while the second one points to the database in the BIN\DEBUG folder. In this way you could keep the original database ready for deployment purposes and schema changes, while, with the second connection you could look at the effective results of your coding efforts.
EDIT Special warning for MS-Access database users. The simple act of looking at your table changes the modified date of your database ALSO if you don't write or change anything. So the flag Copy if Newer kicks in and the database file is copied to the output directory. With Access better use Copy Never.
Committing changes / saving changes across debug sessions is a familiar topic in SQL CE forums. It is something that trips up quite a few people. I'll post links to source articles below, but I wanted to paste the answer that seems to get the best results to the most people:
You have several options to change this behavior. If your sdf file is part of the content of your project, this will affect how data is persisted. Remember that when you debug, all output of your project (including the sdf) if in the bin/debug folder.
You can decide not to include the sdf file as part of your project and manage the file location runtime.
If you are using "copy if newer", and project changes you make to the database will overwrite any runtime/debug changes.
If you are using "Do not copy", you will have to specify the location in code (as two levels above where your program is running).
If you have "Copy always", any changes made during runtime will always be overwritten
Answer Source
Here is a link to some further discussion and how to documentation.

dyanamically change the database name in SqlMapConfig.xml file

I want to change the database name in SqlMapConfig.xml file from the application, does any one help me?
You can override the database when you instantiate the Ibatis mapper instance; I do this for switching between debug and release builds of the application and hence accessing a different target database.
If your xml file is in an assembly called DatalayerAssembly for example, you might have a method for returning your new Ibatis instance based on a database name like this:
public IBatisNet.DataMapper.ISqlMapper CreateNewIbatis(
String serverName,
String databaseName)
{
// Load the config file (embedded resource in assembly).
System.Xml.XmlDocument xmlDoc = IBatisNet.Common.Utilities.Resources.GetEmbeddedResourceAsXmlDocument("SqlMapConfig.xml, DatalayerAssembly");
// Overwrite the connectionString in the XmlDocument, hence changing database.
// NB if your connection string needs extra parameters,
// such as `Integrated Security=SSPI;` for user authentication,
// then append that to InnerText too.
xmlDoc["sqlMapConfig"]["database"]["dataSource"]
.Attributes["connectionString"]
.InnerText = "Server=" + serverName + ";Database=" + databaseName;
// Instantiate Ibatis mapper using the XmlDocument via a Builder,
// instead of Ibatis using the config file.
IBatisNet.DataMapper.Configuration.DomSqlMapBuilder builder = new IBatisNet.DataMapper.Configuration.DomSqlMapBuilder();
IBatisNet.DataMapper.ISqlMapper ibatisInstance = builder.Configure(xmlDoc);
// Now use the ISqlMapper instance ("ibatisInstance") as normal.
return ibatisInstance;
}
I'm using this approach in Ibatis 1.6.2.0 on .Net but the exact SqlMap config file might vary depending by version. Either way the approach is the same; you just might need a different Xml path (i.e. the bit that reads ["sqlMapConfig"]["database"] etc may need changing for your config file)
Hope that helps.

How do I load a dll's config file inside another appdomain

I have an application that needs to load an add-on in the form of a dll. The dll needs to take its configuration information from a configuration (app.config) file. I want to dynamically find out the app.config file's name, and the way to do this, as I understand , is AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
However, since it is being hosted INSIDE a parent application, the configuration file that is got from the above piece of code is (parentapplication).exe.config. I am not able to load another appdomain inside the parent application but I'd like to change the configuration file details of the appdomain. How should I be going about this to get the dll's configuration file?
OK, in the end, I managed to hack something together which works for me. Perhaps this will help;
Using the Assembly.GetExecutingAssembly, from the DLL which has the config file I want to read, I can use the .CodeBase to find where the DLL was before I launched a new AppDomain for it. The *.dll
.config is in that same folder.
Then have to convert the URI (as .CodeBase looks like "file://path/assembly.dll") to get the LocalPath for the ConfigurationManager (which doesn't like Uri formatted strings).
try
{
string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
string originalAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
Uri uri = new Uri(String.Format("{0}\\{1}.dll", originalAssemblyPath, assemblyName));
string dllPath = uri.LocalPath;
configuration = ConfigurationManager.OpenExeConfiguration(dllPath);
}
catch { }

Can't get rid of a deleted Settings reference in DataSet.Designer.vb

I had a connection string to a MS Access DB file, Foo.accdb, defined and used in my project. It was defined as a connection string Setting in the Settings section of my project properties. The program referenced the connection string setting and everything worked fine.
Then I decided to replace Foo.accdb with two different DB files, A.accdb and B.accdb each of which would be used under different circumstances. I added connection strings for them in Settings and removed the Setting definition for Foo.accdb connection string.
The name of my application is Foo and the name of the Foo.accdb connection string was FooConnectionString.
But now when I build the program both in debugger and for release I get the following error message:
'FooConnectionString' is not a member of 'Foo.My.MySettings'.
The offending reference, in file FooDataSet.Designer.vb, is:
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute()> _
Private Sub InitConnection()
Me._connection = New Global.System.Data.OleDb.OleDbConnection
Me._connection.ConnectionString = Global.Foo.My.MySettings.Default.FooConnectionString
End Sub
What is going on here? FooConnectionString is not in any other file in the project directory nor in the My Project subdir. I completely got rid of it in my code and in my project properties yet it persists in FooDataSet.Designer.vb (whatever that is).
While researching this on the web I saw a recommendation to select the FooDataSet.xsd file, right click it and execute the "Run Custom Tool" option. I did this and it appears to rebuild FooDataSet.Designer.vb (the time stamp changes) but the problem persists.
I also tried removing the offending reference by manually editing FooDataSet.Designer.vb but that gave me some other error message.
Why is this old reference staying around and what can I do about it?
This is a standalone app. I'm using VS2008 Standard Ed., VB.Net 3.5
Thanks.
Open the FooDataSet XSD file in a text editor. Right click on dataset in the solution explorer and select "Open With..." and the select XML (text) Editor or open it outside the solution.
Look for the <Connections> tag near the top of the file. Remove the line that looks like this
<Connection AppSettingsObjectName="Settings" AppSettingsPropertyName="FooConnectionString" ConnectionStringObject="" IsAppSettingsProperty="true" Modifier="Assembly" Name="FooConnectionString(Settings)" ...

Resources