I've got this code in my Winforms app to create a table in an existing database, (which I created by following what is written here):
private void CreateTables()
{
string connStr = #"Data Source=
(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|
\AYttFM.mdf;Integrated Security=True";
using (var connection = new
System.Data.SqlClient.SqlConnection(connStr))
{
try
{
connection.Open();
using (var command = connection.CreateCommand())
{
StringBuilder sb = new StringBuilder();
sb.Append("CREATE TABLE [dbo].[AssignmentHistory] ");
sb.Append("(");
sb.Append("[Id] INT NOT NULL PRIMARY KEY, ");
sb.Append("[WeekOfAssignment] DATE NOT NULL,");
sb.Append("[TalkType] INT NOT NULL,");
sb.Append("[StudentID_FK] INT NOT NULL, ");
sb.Append("[AssistantID_FK] INT NOT NULL, ");
sb.Append("[CounselPoint] INT NOT NULL");
sb.Append(")");
command.CommandText = sb.ToString();
command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
It runs without complaint, but no table is created. Refreshing both the Data Connection and its Tables folder in Server Explorer in Visual Studio Community 2015 show no tables.
Am I missing something in the code above?
Note: I broke the connStr over several lines above for formatting purposes; in the actual code, connStr is all on one line.
I'm also not able to connect to the .mdf file via LINQPad, using the "Default LINQ to SQL" and SQL Server Provider and navigating to the .mdf file in my project (C:\AYttFMApp\AYttFMScheduler\AYttFMScheduler\AYttFM.mdf). It tells me there is a network error:
I get that whether I use the default Server ".\SQLEXPRESS" or whether I set it to my machine name (which is the only entry beneath "Servers" in Visual Studio's Server Explorer).
UPDATE
I rebooted my laptop, but it didn't help. Server Explorer's Data Connections show nothing, even after I refresh, and trying to add one, with my machine name as the Server Name (after all, that is what it says the Server is there in Server Explorer) and selecting the .mdf file gives me the same error when testing the connection as LINQPad does.
UPDATE 2
Curiouser and curiouser: Now when I run my app, when it gets to the Create Table code, I get an exception msg that says the AssignmentHistory table has already been created. Yet if I look at Server Explorer, although the database itself is back again, its Tables folder is still empty. How can the table both be there and not be there?
I'm still wondering if the properties set on the .mdf file are wrong; as I wrote in a comment below, the properties are all the defaults: "Copy to Output Directory" is set to "Copy Always" and "Build Action" is set to "Content" Should either of these be changed?
If the code does not throw any exceptions on line command.ExecuteNonQuery() then the query did finish and the table should be there. It could be that you are just looking at the wrong database as you are using the LocalDb. If the project has included the .MDF as a file and it is marked to always be copied to the destination directory then what is happening is that VS is always looking at the unaltered copy and the Execute statement always completes during debugging because the unaltered copy is always replacing the copy that is used at run time.
The DataDirectory specifies a placeholder for a location that is usually assigned in the application startup. You can get the full path to the actual .mdf file being used like so:
var fullFilePath = System.IO.Path.Combine(AppDomain.CurrentDomain.GetData("DataDirectory").ToString(), "AYttFM.mdf");
I have appended the name of your .mdf LocalDb to the end of the path.
You can add this line of code and get the path of the file and then open this instance up with the Visual Studio table designer.
Alternatively you can change the connection string and hard code it to a specific instance of your .mdf file that is guaranteed not to change when you do a build on the project.
Edit based on your latest edits
"Object reference not set to an instance of an object" is what I get
after running the line you provided.
I made the assumption you were setting the DataDirectory location manually, my apologies. If you do not set the variable manually then for a windows application the default location is the .exe path. So the code should be updated to the following:
var fullFilePath = System.IO.Path.Combine(System.Reflection.Assembly.GetExecutingAssembly().Location.ToString(), "AYttFM.mdf");
This will probably resolve to something like .\yourProjectFolder\debug\bin\AYttFM.mdf.
The properties are all the defaults: "Copy to Output Directory" is set
to "Copy Always" and "Build Action" is set to "Content"
So that affirms what I wrote earlier. Every time you do a build it will copy the .mdf to your executable directory and basically refreshes the database to its original state. Note that you can do multiple runs from visual studio which means that if everything has already been compiled and nothing has changed a new .exe and content will not be re-copied over the existing one. This is why you are sometimes seeing an exception and other times you are not, it just depends on if the .mdf was overwritten or not.
Should either of these be changed?
This should be OK but it depends on if it's ok to start with a clean slate every time. That is really up to you, here are the available options you have:
From MSDN - File Properties
Copy to Output Directory Property
This property specifies the conditions under which the selected source
file will be copied to the output directory. Select Do not copy if the
file is never to be copied to the output directory. Select Copy always
if the file is always to be copied to the output directory. Select
Copy if newer if the file is to be copied only when it is newer than
an existing file of the same name in the output directory.
If you want to open the .mdf file all you have to do is double click on it in the VS project, it should open up in Server Explorer -> Data Connections. There is no reason to open the output file (the copy of the .mdf) in your designer, I would only edit the file in your project as with your current setup this is the master file that will overwrite the output file every time.
I have no experience with LINQPad so I can't say if this application can attach to a LocalDb instance or not. Here is a post about how to possibly do this from a previous SO question.
Open SQL Server configuration manager and check if your server is running. If it's not - then run it:
Related
I have a local DB that I have in an application. When I install it on another machine I get the error
Unable to update database.. .mdf is read only.
I was able to get around it by editing my permissions on the .mdf and log file themselves. I did some research and noticed that I may want to install the database to a shared folder. However, I am not sure how to do that and the answers I did come across did not make a whole lot of sense to be.
//My connection string
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|AssetDatabase.mdf;Integrated Security=True");
Any guidance would be greatly appreciated. I am learning.
Just go to the program files and find the folder of the installed program.
Just right click the .mdf file in the folder and click PROPERTIES.
In PROPERTIES TAB -> SECURITY -> you'll see Group or Usernames.
In that select the User to which u want to give Access to the file.
If for that user the PERMISSION is not set to FULL CONTROL.
TO CHANGE PERMISSIONS -> CLICK EDIT.
Now the Group or Username box will open.
In that Select The User -> Select FULL CONTROL in Permission Box.
Now follow the steps for the log file too. IF Needed.
OR
Just install your application in different folder other than ProgramFile(x86)
The MDF file would be readonly either because the readonly file attribute flag is set, in which case you have to unset it, or another program has the MDF file locked as readonly. Are you running a version of SQL server that is using that file?
I've never seen a connection to the MDF file directly, usually it's done via the server, and the server will manage all the IO for the MDF file.
E.g. a typical connection string for SQL Server:
Database=<dbname>;Server=<servername>;MultipleActiveResultSets=True;Connection Timeout=10;User Id=<username>;Password=<password>;
Additional links:
1) Failed to update .mdf database because the database is read-only (Windows application)
2) Failed to update database because it is read-only
3) Failed to update database "*.mdf" because read only EntityFramework
4) http://www.codeproject.com/Questions/183758/Failed-to-update-mdf-database-because-the-database
First stop the SQLEXPRESS service from local-Services menu and then try to move and connect the database again by attaching database option in SQLEXPRESS. it should work. it works for me. :)
I solved the same problem as follows:
While creating "Setup", I manually added my database files database.mdf and database_log.ldf into the Application Folder file. But after adding these files, make sure that the ReadOnly option in the Properties section is False.
Also "connectionString" I use:
connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\database.mdf;Integrated Security=True;Connect Timeout=30"
just remove the .mdf file location to c:\ or desktop or anywhere but not in
%program file directory
if your database file on the C volume,
try to move the .mfd file to D volume
I am trying to save Name Value pair in settings dynamically. I can see the new saved values dynamically. But, when I access the settings page from the property window , it shows the same old value. Here is the code :
Properties.Settings.Default.Name = textBox1.Text;
Properties.Settings.Default.Age = textBox2.Text;
Properties.Settings.Default.Save();
Any Suggestions?
Assuming you are testing your application with Visual Studio, your problem happens because, when you are changing the setting of your application you aren't changing the original setting file. When Visual Studio starts running an application, it creates a folder inside the directory where your code is named "obj/Debug" or "obj/Release" and copies all your DLLs and resources into that folders, including settings files.
This means that changes to settings will be reflected in your "obj/Debug/yourappname.exe.config" and not in the original file. If you open this file, for example, with a text editor you'll see the contents have changed. Remember that every time you recompile your application in Visual Studio and start running this file will be replaced by the original, losing your new settings.
You can manually run your .exe application inside that folder and validate if your settings have persisted.
After compile the settings file gets deployed into a yourapplication.exe.config file. This is the file you are changing (/Debug/app.exe.config). If you want to see changes in your "property window" you have to manually open the .settings file and edit the xml.
Note: after changing the .config file the changes are persistent .. but only until you compile your application again.
The solution->Properties->Settings is where you set the default values. User settings can be changed at run-time, and will persist with your application, but they are not written back to your visual studio project.
In your example, if you run the program again on subsequent times (* not by hitting debug / rebuild in visual studio), your settings that are saved in your snippet will have been persisted.
Imagine that your program has been deployed on user's pc's - there shouldn't be a mechanism for that to change your visual studio project settings file.
This is probably a stupid mistake of me.. but I can't seem to understand it.
I've created a new, empty C# Windows Forms application.
I added a Database (Based on a dataset) and have the file stored in my solution explorer.
I've added a table Test with column Name.
I add a record using new SqlCeCommand("insert into Test values('Name')", new SqlCeConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString)).ExecuteNonQuery();
However, I've even tried retrieving the same data and it all works perfectly.
But when I stop my project, and rebuild it.. all data is gone again?
Is there a way to fix this, or will this fix itself when I'll start using this project for what it is intended (Without the 500 rebuilds a day?)
Your database file is listed in the project with this property
Copy to destination directory = Copy Always
If this is true then every time you restart the project a fresh (empty) copy of the database file is copied from the project directory to the output directory (BIN\DEBUG or BIN\RELEASE) overwriting the database file used in the previous run. You could avoid this changing the property to Copy Never or Copy if newer
The answer given by steve keeps copying the database over the existing one, which results in removing all data.
I've managed to fix this by putting "Copy Always" on, then in the explorer move the database to a different location and add it to the project. This way the database will never be overwritten and can be used in the program!
(However, this will probably raise a issue if/when I publish the project to another computer)
In a project, I have a local database, (I am using the datagrid to view the data), but the problem is that when I insert into database using the insertion query, the insertion is not lasting, i.e. when I rerun the application, the database is not changed and the changes are not reflected in the database view (view table data in Visual Studio).
The insertion query is:
string dbCon = new System.IO.FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName + "\\MyDatabase.sdf";
SqlCeConnection dbconnection = new SqlCeConnection("datasource=" + dbCon);
dbconnection.Open();
String Insert = "insert into MainTable(LineID,Date,Connection_Type) Values('5','5/8/2012','commercial')";
SqlCeCommand cmd = new SqlCeCommand(Insert, dbconnection);
//// Execute the command
cmd.ExecuteNonQuery();
dbconnection.Close();
Now when this code runs, the datagrid is updated, but the changes are not permanent. What is it that I am doing wrong?
I am using Visual Studio 2010 Ultimate and Windows 7
In what folder is your application running? If it is in the Program Files tree you likely do not have write permissions to the sdf file (especially on Windows 7 unless you have turned off UAC or are elevating your app prior to execution).
Even if that is not your short term issue I would recommend finding a different place for the sdf file, such as one of the AppData locations. Expecting to be able to write to your install location is not a guaruntee and depends on how and where your app is deployed.
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\MyDatabase.sdf" is the path to your application folder. Depending on installation options your file may not be installed there. Use a connection string of "DataSource=|DataDirectory|\\MyDatabase.sdf;..." as described here.
Even if your data is actually stored there, depending on user permissions the user may not be able to write to that directory. Also, when the user uninstalls or updates your app, his data will be deleted. People don't like that. You should copy the data to a user-writable folder; the earlier link shows how to do that as well.
If you have a Visual Studio project with a database a part of your project, it will probably have the "Copy to Output Directory" property set to "Copy". That means each time you run in the debugger you get a brand-new database copied from your source project, overwriting whatever was there before. Any changes will be in this temporary output folder, not in your original source data. When you debug the app again, the temporary copy is deleted. Further explanation in this answer.
Have som problem with Access 2007, and visual studio 2008 C#.
each time i try to run my program deletes all records in access. the fields are still there but only records disappears!!!
conn.accdb exist in my solution explorer with
path : C:\Documents and Settings\kizmo\Dokumenter\Visual Studio 2008\Projects\conn\conn\conn.accdb
Here i have another copy of conn.accdb and this is the one which all records deletes after running......
C:\Documents and Settings\kizmo\Dokumenter\Visual Studio 2008\Projects\conn\conn\bin\Debug
i am not sure why i have to have 2 exactly samme database file i different directories.
thx
Sounds like the database file has been included in your project as "Copy to Output Directory". Your application is modifying the one in the bin directory, but everytime you compile, your blank database overwrites it. In the properties for that file in your project, turn off the "Copy to Output Directory" option. (You will then probably have to to change the path to the database.)
Also note that what you are seeing isn't necessarily bad in development. Your actual application, I'm assuming, will not be using the database in your Visual Studio bin folder, but somewhere else. Typically you use the ConnectionString node in your app.config to direct this to the correct location.