0

I am trying to add an SQL database to my project. I have been successful when using an explicit path, but if I use a relative path |DataDirectory|\Data\Database.mdf the console appears to be be writing data to the database, but looking in the server explorer at the database afterwards shows not data. There are a couple of other questions that get close to answering, but scouring Stack, I have been unable to locate an answer that works or comes close to addressing.

EDIT Per the suggestions below I have attempted the fixes, however, just to clarify. The program appears to connect and write to the database as expected, but when I look at the database structure, no table is created, no data is inserted, even though the program runs with no errors

enter image description here

<connectionStrings> <add name="rData"providerName="System.Data.SqlClient"connectionString="Data Source=(LocalDB)\MSSQLLocalDB; Initial Catalog=TestRecipeDatabase;AttachDbFilename=|DataDirectory|\Data\TestRecipeDatabase.mdf;Integrated Security=True" /> </connectionStrings>

 public void connectToDB(string action)
        {
            var connectionString = ConfigurationManager.ConnectionStrings["rData"].ConnectionString;
            Console.WriteLine(connectionString);
            SqlConnection conn = new SqlConnection(connectionString);

            if (action == "firstRun")
            {
                conn.Open();
                // Creates the Database
                try
                {
                    using (SqlCommand createDBTable = new SqlCommand("" +
                        "CREATE TABLE RecipeStorage" +
                        "(" +
                        "rname char(50) NOT NULL, " +
                        "ringredients text, " +
                        "rdirections text" +
                        ");", conn))
                        createDBTable.ExecuteNonQuery();
                    Console.WriteLine("Created Database");
                }

                catch (SqlException e)
                {
                    Console.WriteLine(e.Message);
                    System.Diagnostics.Trace.WriteLine(logTime + " " + e.Message);
                }

                // Sets the primary key to rname
                try
                {
                    using (SqlCommand setPrimaryKey = new SqlCommand("ALTER TABLE RecipeStorage ADD PRIMARY KEY (rname);", conn))
                        setPrimaryKey.ExecuteNonQuery();
                    Console.WriteLine("Set Primary Key to Recipe Name");
                }

                catch (SqlException e)
                {
                    Console.WriteLine(e.Message);
                    System.Diagnostics.Trace.WriteLine(logTime + " " +e.Message);
                }

                // Adds an initial recipe
                try
                {
                    using (SqlCommand firstLine = new SqlCommand("INSERT INTO RecipeStorage (rname, ringredients, rdirections) VALUES ('espresso', 'Hot water, coffee'," +
                        "'put coffee through espresso machine with hot water into cup, enjoy');", conn))
                        firstLine.ExecuteNonQuery();
                }

                catch (SqlException e)
                {
                    Console.WriteLine(e.Message);
                    System.Diagnostics.Trace.WriteLine(logTime + " " + e.Message);
                }
                conn.Close();
            }
        }

As mentioned above, this totally works when using an explicit path for the data connection C:\User\User\Projects\CSharp\RecipeHandler\Data\TestRecipeDatabase.mdf

But does not work using the relative path. Ideally I would want to be able for this to run on any computer which obviously would not have the database in same place

DSMTurboAWD
  • 344
  • 1
  • 3
  • 16
  • could you try to build a `SqlConnection` that points to the server? – LONG Apr 20 '17 at 14:08
  • 1
    Check the answers here: http://stackoverflow.com/questions/1833640/connection-string-with-relative-path-to-the-database-file – Rigerta Apr 20 '17 at 14:08
  • Remove the AttachDbFilename (mdf file name) it is not necessary and can cause issue. The server know the location of the mdf from the database name Catalog=TestRecipeDatabase. When the Catalog is created a filename is stored in the SQL Server. – jdweng Apr 20 '17 at 14:20
  • I will try the answer linked by rigerta, I looked at this before but it still seemed to not modify the DB, as mentioned, it _looks_ like it is working, but no changes to the DB is made. jdweng I will try this as well, but since the `TestRecipeDatabase` is not on the root of the project, do I need to add the path: `data\TestRecipeDatabase` ? – DSMTurboAWD Apr 20 '17 at 14:30
  • I would offer a couple of suggestions. First, don't use the text datatype. It has been deprecated for over a decade now in favor of varchar(max). Second, you need to read about normalization. A recipe needs at a bare minimum 2 tables. One for the recipe information and another for the ingredients. Storing ingredients in a comma delimited list like you have violates 1NF and is nothing but painful to work with. – Sean Lange Apr 20 '17 at 14:31
  • @SeanLange Yes, I agree, for the moment, without complicating the illustration, it was easier to use a single table, but I gather it would be beneficial to use like, recipe and recipeDetail or somesuch so that the formatting is nicer? With 'text' as a datatype, I did not realize it was depreciated, With VarChar can you use (max) or do you have to specify bits? (I can probably look that up) – DSMTurboAWD Apr 20 '17 at 14:36
  • You don't have to use max. You can specify the size up to 8000. The biggest issue with text is you can't index it, you can't search it, you can't do much with it at all unless you cast it to a usable datatype which defeats the purpose. I would also drop the "r" prefix on your columns but that is personal preference. – Sean Lange Apr 20 '17 at 14:39
  • Here is the documentation on text. https://learn.microsoft.com/en-us/sql/t-sql/data-types/ntext-text-and-image-transact-sql – Sean Lange Apr 20 '17 at 14:40
  • @jdweng I changed the app.config to reflect the changes you suggested, again, it _looks_ like it is working, but in the server explorer, no changes are made to the database (data connection) – DSMTurboAWD Apr 20 '17 at 14:46
  • How are you verifying changes? Use SQL Server Management Studio (SSMS) which comes with SQL Server and connect to database. You can use SSMS Explorer to query the database to confirm changes are being made. – jdweng Apr 20 '17 at 16:35
  • @jdweng I am still a bit new to SQL in Visual Studios, but I am looking at the Server Explorer (in Visual Studio) > Data Connections > {database name} which, when I have the explicit path, it shows that the data is created correctly. I am not using the SSMS at this time, though I do have it installed – DSMTurboAWD Apr 20 '17 at 16:54
  • So what is not working if data was created correctly? Do you mean that you can add data but not update an existing value? To change an existing value you must reference a row by its key value. Otherwise a new row is added to data base and both old and new value are put in database. – jdweng Apr 20 '17 at 19:17
  • @jdweng The data is not created, the code appears to run and run successfully, but it does not save any changes to the database. See the bolded clarification above – DSMTurboAWD Apr 20 '17 at 19:44
  • You made rname the primary key. When you have a primary key it has to be unique. Also 'Insert' will give an error when a primary key already exists. 'Insert' returns a integer indicating the number of rows in the database that changed. So you must check the return value from 'Insert' and if zero then you must do an 'Update' to change value. 'Update' will fail if primary key isn't in database so you cannot just do an 'Update' without doing the 'Insert' first. – jdweng Apr 21 '17 at 09:24

0 Answers0