24

He creado una nueva aplicación ASP.NET MVC 4 y me gustaría que primero use el código. Sin embargo, inicialmente no parece crear el archivo de la base de datos si no existe. Si elimino el archivo .mdf de la carpeta App_Data, entonces consigo la siguiente excepción cuando la aplicación intenta acceder a la base de datos:Excepción cuando el código intentó crear la base de datos por primera vez

System.Data.SqlClient.SqlException: Cannot attach the file '<path-to-db-file>.mdf' as database '<my-db-file-name>'. 

Si me quedo en la aplicación en el depurador, entonces puedo ver que la excepción se produce en el método InitializeSimpleMembershipAttribute :: OnActionExecuting cuando se llama a LazyInitializer.EnsureInitialized. La excepción es capturado:

[System.Reflection.TargetInvocationException] {"Exception has been thrown by the target of an invocation."} System.Reflection.TargetInvocationException 

Con una excepción interna de:

[System.InvalidOperationException] {"The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588"} System.InvalidOperationException 

¿Qué tiene entonces la primera excepción que he mencionado anteriormente como la excepción interna de ello.

¿Alguna idea de lo que estoy haciendo mal?

actualización

he acaba de intentar con una nueva aplicación MVC4 marca. Puedo replicarlo haciendo lo siguiente:

  1. Cree la aplicación MVC en el asistente VS.
  2. Ejecute la aplicación por primera vez y vaya a la página de inicio de sesión (tenga en cuenta que ahora se genera el archivo mdf).
  3. Borre el archivo mdf y regrese a la página de inicio de sesión. La excepción ahora se arroja.
+7

¿alguna vez entendiste esto? – Eonasdan

+0

@Eonasdan, un año después, sí. Por favor mira mi respuesta. – joelmdev

Respuesta

0

Debe detener su instancia de IISExpress y reiniciarla de nuevo (presionando F5 en su Visual Studio). Entonces podrás crear la base de datos nuevamente.

2

Puede manejar Código primera inicialización de base de datos en el método Application_Start de archivo Global.asax en la carpeta raíz de su proyecto, como la siguiente:

protected void Application_Start() 
    { 
     Database.SetInitializer<MyDBContext>(null); 
    } 

Si pasa nula a SetInitializer que no creará ni altere sus tablas de base de datos, debe hacerlo manualmente.

La razón por la cual la base de datos no se vuelve a generar es que Application_Start se activa solo una vez durante la vigencia de la aplicación.

+1

Esto ya no es la mejor práctica en MVC4. Use las clases en la carpeta App_Start en su lugar. – kingdango

2

El código generado por MVC funciona con una cadena de conexión de base de datos llamada "DefaultConnection". Si utilizó un nombre diferente en Web.config, es necesario hacer referencia a este nombre en:

  1. InitializeSimpleMembershipAttribute.SimpleMembershipInitializer.ctor() en InitializeSimpleMembershipAttribute.cs).
  2. UsersContext.ctor() en AccountModel.cs

(o simplemente buscar "DefaultConnection" en su proyecto).

1

Nunca debe eliminar los archivos .mdf autocreados en Explorer, solo a través de las herramientas de administración de SQL o en el Explorador de objetos.

El problema que está recibiendo (y puede replicar en los pasos que ha proporcionado) es que la base de datos aún está registrada en LocalDb.

+0

LocalDB admite la base de datos como archivo, por lo que esto no es necesariamente cierto. Consulte http://blogs.msdn.com/b/sqlexpress/archive/2011/07/12/introducing-localdb-a-better-sql-express.aspx – joelmdev

4

Si se mira a la clase InitializeSimpleMembershipAttribute de la aplicación verá el siguiente método reemplazado de la clase ActionFilterAttribute del que hereda:

public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     // Ensure ASP.NET Simple Membership is initialized only once per app start 
     LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock); 
    } 

Aviso ese comentario. La aplicación comprueba una vez por ejecución para garantizar que la Membresía simple se haya inicializado correctamente. Mira las variables privadas en la parte superior de la clase:

private static SimpleMembershipInitializer _initializer; 
    private static object _initializerLock = new object(); 
    private static bool _isInitialized; 

Todos ellos son estáticas y todo lo que se pasan como árbitros. El más importante aquí para su situación es _isInitialized. Lo que hace LazyInitializer.EnsureInitialized es comprobar el indicador _isInitialized y, si es falso, inicializa el objetivo de referencia que se pasa, en este caso el _initializer de tipo SimpleMembershipInitializer. En ese punto, establece la bandera en verdadero y avanza. Si LazyInitializer.EnsureInitialized ve que la bandera es verdadera, no hace más que devolver el objetivo. Como ese indicador es una variable estática, persiste su valor durante la vida de la aplicación, lo que significa que después de esa primera inicialización EnsureInitialized siempre devolverá el destino aunque el archivo de la base de datos ya no exista. En otras palabras, si elimina el archivo .mdf después de la inicialización, la aplicación no lo sabrá y se lanzarán excepciones cuando la aplicación intente leer o escribir desde la base de datos. Para resolver esto, debe reiniciar la aplicación, lo que significa eliminar el servidor de desarrollo si eso es lo que está utilizando o reiniciar la aplicación en IIS.

Así que ese es el problema al que se enfrentan, pero sospecho que muchos de los que están corriendo esta pregunta están teniendo un problema similar pero diferente al recibir un mensaje de error similar a éste cuando intentan iniciar sesión:

CREATE FILE encontró el error 5 del sistema operativo (Acceso denegado.) Al intentar abrir o crear el archivo físico 'C: \ path \ to \ your \ project \ App_Data \ dbfile.mdf'. CREATE DATABASE failed. Algunos de los nombres de archivos en la lista no se pudieron crear. Verificar errores relacionados.

Esto es muy fácil de resolver ya que también lo cubriré rápidamente aquí.

De forma predeterminada Visual Studio 2012 utiliza una versión simplificada de SQL Server Express llamada LocalDB. LocalDB se activará como un proceso secundario de la aplicación, y si está ejecutando su aplicación en el servidor de desarrollo de Visual Studio (por ejemplo, http: // localhost: [puerto] es lo que aparece en su navegador) entonces está ejecutando tanto la aplicación y LocalDB bajo su cuenta de usuario, no bajo SYSTEM o NETWORKSERVICE. Todo lo que tiene que hacer para solucionar esto es asignar permisos de modificación a su usuario para la carpeta App_Data de su proyecto. Pruebe de nuevo el inicio de sesión y el archivo .mdf se debe crear correctamente.

Si tienes curiosidad, se puede aprender más acerca de LocalDB here.

+0

La modificación de permisos en la carpeta App_Data resolvió mi problema. Espero que esto ayude a otros. – BrianLegg

9

se metió en el mismo problema y ha encontrado mi solución here. todo lo que tiene que hacer es dejar LocalDB al abrir el símbolo del sistema VS desarrollador y entrar (sin comillas):

"parada v11.0 sqllocaldb.exe"

"sqllocaldb.exe eliminar v11.0"

La próxima vez EF se regenerará el archivo, así como el PP.

+0

Su enlace me ayudó :) –

+2

Las instancias de LocalDB pueden tener otros nombres. La ejecución de 'sqllocaldb info' mostrará una lista de todas las instancias de LocalDB existentes. – Paul

0

lo arreglaron para mí cuando yo estaba recibiendo este error es que he cambiado la cadena de conexión en el archivo app.config de mi proyecto VS .

he añadido esto en la cadena de conexión:

<connectionStrings> 
<add name="Blog" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Integrated Security=true;AttachDbFileName=C:\Users\kostadin\Database1.mdf" providerName="System.Data.SqlClient" /> 

Espero que esto ayude a alguien más

012.
Cuestiones relacionadas