Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Erro SQL com Entity Framework

Bom dia Pessoal,

Estou trabalhando em uma aplicação já existente feita em C# utilizando basicamente XAML e Entity Framwork trabalhando com um banco de dados em arquivo .mdf.

Esta aplicação possui um projeto que é seu instalador. Recompilando a solução e fazendo a instalação pelos arquivos gerados pelo instalador, ao abrir a aplicação na maquina do cliente acontece o seguinte erro:

Exception throw at level 1: A file activation error occurred. The physical file name '\App_Data\Psbn.mdf' may be incorrect. Diagnose and correct additional errors, and retry the operation.
CREATE DATABASE failed. Some file names listed could not be created. Check related errors.
Target Site: Void OnError(System.Data.SqlClient.SqlException, Boolean, System.Action`1[System.Action])
Stack Trace:    em System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)

Este aqui é minha connection string:

  <connectionStrings>
    <add name="PsbnEntities" connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Psbn;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\App_Data\Psbn.mdf" providerName="System.Data.SqlClient"/>    
  </connectionStrings>

Será que alguém pode me ajudar a entender melhor o problema e o que pode estar ocasionando isso ?

Obrigado

7 respostas

Verifica se o arquivo '\App_Data\Psbn.mdf' está na pasta certinho.

Sim está.

Achei que o problema era o caminho do arquivo.

The physical file name '\App_Data\Psbn.mdf' may be incorrect

Como a minha connection String está utilizando o |DataDirectory| para mapear o local do .mdf pensei que o |DataDirectory| não estivesse trazendo a endereço completo. Então fiz a seguinte alteração, na minha classe Context do EF inclui a seguinte a linha:

AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86));

Após esta alteração o erro continua acontecendo, porem, mudou:

Exception throw at level 1: Cannot create file 'C:\Program Files (x86)\PSBN\App_Data\Psbn.mdf' because it already exists. Change the file path or the file name, and retry the operation.
CREATE DATABASE failed. Some file names listed could not be created. Check related errors.

OBS: O initializer esta configurado para DropCreateDatabaseIfModelChanges

Nossa agora ele tá querendo criar o arquivo. Posta o código aqui pra gente poder analisar.

App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>

    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v12.0"/>
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
    </providers>
  </entityFramework>
  <connectionStrings>
    <add name="PsbnEntities" connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Psbn;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\PSBN\App_Data\Psbn.mdf" providerName="System.Data.SqlClient"/>
    <!--<add name="PsbnEntities" connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Psbn;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\PSBN\App_Data\Psbn.mdf" providerName="System.Data.SqlClient"/>-->


    <!--<add name="PsbnEntities" connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Psbn;Integrated Security=SSPI" providerName="System.Data.SqlClient" />-->
  </connectionStrings>
</configuration>

Classe PsbnContext.cs

namespace Netzsch.PSBN.Data
{
    public class PsbnContext : DbContext
    {
        public PsbnContext() : base("PsbnEntities")
        {
            AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86));            
            Database.SetInitializer<PsbnContext>(new PsbnContextInitializer());
        }

        #region Entities

        public DbSet<Abrasividade> Abrasividades { get; set; }

        public DbSet<Acionamento> Acionamentos { get; set; }

        public DbSet<Bomba> Bombas { get; set; }

        public DbSet<BombaGrupo> BombasGrupos { get; set; }

        public DbSet<BombaConexao> BombasConexoes { get; set; }

        public DbSet<BombaFce> BombasFce { get; set; }

        public DbSet<BombaMaterial> BombasMateriais { get; set; }

        public DbSet<Conexao> Conexoes { get; set; }

        public DbSet<DesenhoDimensional> DesenhosDimensionais { get; set; }

        public DbSet<FormaConstrutivaExecucao> FormasConstrutivasExecucoes { get; set; }

        public DbSet<Geometria> Geometrias { get; set; }

        public DbSet<Material> Materiais { get; set; }

        public DbSet<MotoRedutor> MotoRedutores { get; set; }

        public DbSet<ParteGiratoria> PartesGiratorias { get; set; }

        public DbSet<SemaforoAbrasividade> SemaforosAbrasividade { get; set; }

        public DbSet<VedacaoEixo> VedacoesEixo { get; set; }

        public DbSet<SalesOffice> SalesOffices { get; set; }

        #endregion

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // Configure the Abrasividade Entity
            modelBuilder.Entity<Abrasividade>()
                .ToTable("Abrasividades")
                .Property(a => a.Id)
                .HasColumnName("AbrasividadeId");

Classe PsbnContextInitializer.cs

namespace Netzsch.PSBN.Data
{
    class PsbnContextInitializer : DropCreateDatabaseIfModelChanges<PsbnContext>
    {
        protected override void Seed(PsbnContext context)
        {
            // Execute the Insert Data Query
            Debug.WriteLine("Starting to run the Seed Script...");
            string query = System.IO.File.ReadAllText("Resources\\PsbnData.sql");
            context.Database.ExecuteSqlCommand(query);
            Debug.WriteLine("Finished running the Seed Script.");

            // Execute the Update Data Query
            Debug.WriteLine("Starting to run the Update Data Script...");
            string queryUpdate = System.IO.File.ReadAllText("Resources\\UpdatePressaoRecomendadaGrupo.sql");
            context.Database.ExecuteSqlCommand(queryUpdate);
            Debug.WriteLine("Finished running the Update Data Script.");

          base.Seed(context);
        }
    }
}           
solução!

Acho que é algum problema de permissão de escrita. Tenta fazer com que escreva na AppData ao invés de escrever nos arquivos de programa.

AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));

André,

A principio ao AppData não foi a solução, testei quando vc postou, mas quando alteração a linha do AppDomain e recompilei a aplicação o mesmo erro continua.

A pessoa que desenvolveu a aplicação utilizou este cara para gerar o meu instalador:

http://learn.flexerasoftware.com/content/IS-EVAL-nstallShield-Express

Peguei um backup antigo da aplicação, com um msi gerado pela pessoa que desenvolveu e instalei em outra maquina. Funcionou 100%, quando eu recompilo e gero um novo instalador o erro é apresentado.