¿Por qué falla el guardar cambios en una base de datos?

Tengo el siguiente código de C # en una aplicación de consola.

Cada vez que depuro la aplicación y ejecuto la consulta1 (que inserta un nuevo valor en la base de datos) y luego ejecuto query2 (que muestra todas las entradas en la base de datos), puedo ver la nueva entrada que inserté claramente. Sin embargo, cuando cierro la aplicación y verifico la tabla en la base de datos (en Visual Studio), desaparece. No tengo idea de por qué no está guardando.

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(); } } } 

EDITAR: Olvidé mencionar que estoy usando SQL Server Compact Edition 4 y VS2012 Express.

Es un problema bastante común. Usas el | DataDirectory | cadena de sustitución. Esto significa que, al depurar su aplicación en el entorno de Visual Studio, la base de datos utilizada por su aplicación se encuentra en la subcarpeta BIN\DEBUG (o variante x86) de su proyecto. Y esto funciona bien, ya que no tiene ningún tipo de error al conectarse a la base de datos y realizar operaciones de actualización.

Pero luego, sales de la sesión de depuración y miras tu base de datos a través del Visual Studio Server Explorer. Esta ventana tiene una cadena de conexión diferente (probablemente apuntando a la copia de su base de datos en la carpeta del proyecto). Busca en sus tablas y no ve los cambios.

Entonces el problema empeora. Reinicia VS para ir a buscar el error en su aplicación, pero tiene su archivo de base de datos enumerado entre sus archivos de proyecto y la propiedad Copy to Output directory está configurada en Copy Always . En este punto, Visual Studio copia el archivo de base de datos original de la carpeta del proyecto a la carpeta de salida (BIN \ DEBUG) y, por lo tanto, se pierden los cambios anteriores.
Ahora, su aplicación inserta / actualiza nuevamente la tabla de destino y no puede encontrar ningún error en su código. (Ahora, no sé si eres ese tipo de persona, pero, después de dos o tres veces de este ciclo, he escuchado varios tipos de palabras feas)

Puede detener este problema cambiando la propiedad Copy To Output Directory para Copy If Newer o Never Copy . También podría actualizar su conexión en el Explorador del servidor para ver la copia de trabajo de su base de datos o crear una segunda conexión. El primero sigue apuntando a la base de datos en la carpeta del proyecto, mientras que el segundo apunta a la base de datos en la carpeta BIN \ DEBUG. De esta forma, puede mantener la base de datos original lista para el despliegue y los cambios de esquema, mientras que con la segunda conexión puede ver los resultados efectivos de sus esfuerzos de encoding.

EDITAR Advertencia especial para los usuarios de la base de datos MS-Access . El simple hecho de mirar tu mesa también cambia la fecha de modificación de tu base de datos si no escribes o cambias nada. Entonces, la bandera Copy if Newer activa y el archivo de la base de datos se copia en el directorio de salida. Con Access, mejor uso Copy Never .

Cometer cambios / guardar cambios entre sesiones de depuración es un tema familiar en los foros de SQL CE. Es algo que hace tropezar a algunas personas. Publicaré enlaces a los artículos de origen a continuación, pero quería pegar la respuesta que parece obtener los mejores resultados para la mayoría de las personas:


Tienes varias opciones para cambiar este comportamiento. Si su archivo sdf es parte del contenido de su proyecto, esto afectará la forma en que se conservan los datos. Recuerde que cuando depure, todos los resultados de su proyecto (incluido el sdf) si están en la carpeta bin / debug.

  • Puede decidir no incluir el archivo sdf como parte de su proyecto y administrar el tiempo de ejecución de la ubicación del archivo.

  • Si está utilizando “copiar si es más reciente”, y los cambios del proyecto que realice en la base de datos sobrescribirán los cambios de tiempo de ejecución / depuración.

  • Si está utilizando “No copiar”, deberá especificar la ubicación en el código (como dos niveles arriba de donde se ejecuta su progtwig).

  • Si tiene “Copiar siempre”, cualquier cambio realizado durante el tiempo de ejecución siempre se sobrescribirá


Fuente de respuesta

Aquí hay un enlace para más discusión y cómo documentar.