2015-12-21 35 views
5

Sto creando un progetto MVC 6 e preferirei utilizzare Classic ADO.net su Entity Framework 7. Tuttavia sta dicendo che non è possibile trovare lo spazio dei nomi per entrambi DataTable e SqlDataAdapter. Ho una dichiarazione usando System.Data e System.Data.SqlClient. La dose non mostra un errore finché non provo a costruire il progetto.Qual è l'alternativa a DataTable con ADO.NET in MVC 6?

Penso di aver letto da qualche parte che questi due nomi di spazi non sono implementati nella nuova versione. Se è così esiste un modo alternativo di farlo o mi manca una dipendenza o utilizzo di una dichiarazione? Codice

:

public static DataTable GetLog(string appName) 
{ 
    DataTable table = new DataTable("ApplicationLog"); 
    SqlDataAdapter da = null; 

    using (SqlConnection conn = DB.GetSqlConnection()) 
    { 
     SqlCommand cmd = new SqlCommand("select * from ApplicationLog where application_name = @appname", conn); 
     cmd.Parameters.Add(new SqlParameter("appname", System.Data.SqlDbType.NVarChar, 100)); 
     cmd.Parameters["appname"].Value = appName; 


     da = new SqlDataAdapter(cmd); 

     int res = da.Fill(table); 
    } 

    return table; 
} 

mia project.json

{ 
    "userSecretsId": "aspnet5-ASPDemo-b25bb1cc-00e6-401e-9f49-5b59c08a030f", 
    "version": "1.0.0-*", 
    "compilationOptions": { 
     "emitEntryPoint": true 
    }, 

    "dependencies": { 
     "Bestro": "1.0.0-*", 
     "EntityFramework.Core": "7.0.0-rc1-final", 
     "EntityFramework.Commands": "7.0.0-rc1-final", 
     "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final", 
     "Microsoft.ApplicationInsights.AspNet": "1.0.0-rc1", 
     "Microsoft.AspNet.Authentication.Cookies": "1.0.0-rc1-final", 
     "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-rc1-final", 
     "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final", 
     "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", 
     "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", 
     "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final", 
     "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", 
     "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", 
     "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final", 
     "Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final", 
     "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final", 
     "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final", 
     "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc1-final", 
     "Microsoft.Extensions.Logging": "1.0.0-rc1-final", 
     "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final", 
     "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final", 
     "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc1-final", 
     "DataTables.AspNet.AspNet5": "2.0.0-beta2" 
    }, 

    "commands": { 
     "web": "Microsoft.AspNet.Server.Kestrel", 
     "ef": "EntityFramework.Commands" 
    }, 

    "frameworks": { 
     "dnx451": { 
      "frameworkAssemblies": { 
       "System.configuration": "4.0.0.0", 
       "System.Data": "4.0.0.0" 
      } 
     } 
    }, 

    "exclude": [ 
     "wwwroot", 
     "node_modules" 
    ], 
    "publishExclude": [ 
     "**.user", 
     "**.vspscc" 
    ], 
    "scripts": { 
     "prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ] 
    } 
} 

ho finito per cercare un sacco di componenti differenti, al fine di cercare di farlo rispettare. Se ci sono riferimenti di utilizzo per favore fatemelo sapere.

risposta

4

ho capito il problema, perché mi piace a me stesso di utilizzare le stored procedure esistenti e le query SQL dinamico nel mio codice C#. La creazione di una nuova entità per ogni query sull'utilizzo di alcune entità esistenti con proprietà nullable per il salvataggio di nuovi risultati di query non è una buona idea. Inoltre mi piace utilizzare Web API per fornire i dati in formato JSON per l'utilizzo nel frontend scritto in JavaScript.

Dall'altro lato Entity Framework contiene il modo di eseguire query SQL di riga e di salvare i risultati nell'oggetto senza entità di utilizzo. Ho pubblicato i frammenti di codice the answer, che è possibile utilizzare. Ricordo brevemente l'idea.

Una necessità di includere la stringa di connessione nel file di configurazione dell'applicazione. Ad esempio è possibile creare appsettings.json con

{ 
    "Data": { 
    "MyDbConnectionString": "Server=(localdb)\\mssqllocaldb;Database=ApplicationDb;Trusted_Connection=True;MultipleActiveResultSets=true", 
    } 
} 

quindi si crea manichino classe del contesto

public class MyDbContext : DbContext 
{ 
} 

senza qualsiasi entità. Utilizzerai lo DbContext solo per contenere la connessione al database.

Quindi si scrive Startup.cs che costruisce la proprietà Configuration in base al contenuto di "appsettings.json".

public class Startup 
{ 
    // property for holding configuration 
    public IConfigurationRoot Configuration { get; set; } 

    public Startup(IHostingEnvironment env) 
    { 
     // Set up configuration sources. 
     var builder = new ConfigurationBuilder() 
      .AddJsonFile("appsettings.json") 
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true) 
      .AddEnvironmentVariables(); 
     // save the configuration in Configuration property 
     Configuration = builder.Build(); 
    } 
    public void ConfigureServices(IServiceCollection services) 
    { 
     // Add framework services. 
     services.AddMvc() 
      .AddJsonOptions(options => { 
       options.SerializerSettings.ContractResolver = 
        new CamelCasePropertyNamesContractResolver(); 
      }); 
     services.AddEntityFramework() 
      .AddSqlServer() 
      .AddDbContext<MyDbContext>(options => { 
       options.UseSqlServer(Configuration["Data:MyDbConnectionString"]); 
      }); 
    } 
    ... 
} 

Ora avete MyDbContext iniettato e si può usare in un contesto ed è possibile utilizzare

using (var cmd = MyDbContext.Database.GetDbConnection().CreateCommand()) { 
    cmd.CommandText = "select * from ApplicationLog where application_name = @appname"; 
    if (cmd.Connection.State != ConnectionState.Open) 
     cmd.Connection.Open(); 

    cmd.Parameters.Add(new SqlParameter("@appname", SqlDbType.NVarChar, 100) { 
     Value = appName 
    }); 

    da = new SqlDataAdapter(cmd); 

    int res = da.Fill(table); 
} 

Io personalmente preferisco usare List<dynamic> e ExecuteReader/ExecuteReaderAsync invece di DataTable (vedere il codice da the answer) , ma non è così importante.

+0

Grazie. Questo mi porterà sulla strada giusta. Tuttavia sto ricevendo un errore nel file startup.cs su options.UseSqlServer (Configuration ["Data: MyDbConnectionString"]); Dice DbContextOptionBuilder id definito in un assymbly che non è referencedThank tu. Questo mi porterà sulla strada giusta. Tuttavia sto ricevendo un errore nel file startup.cs su options.UseSqlServer (Configuration ["Data: MyDbConnectionString"]); Dice DbContextOptionBuilder id definito in un asson non a cui non si fa riferimento – Dblock247

+1

@ Dblock247: siete i benvenuti! 'UseSqlServer' è definito in' EntityFramework.MicrosoftSqlServer'. Dovresti verificare che 'usando Microsoft.Extensions.DependencyInjection;' e 'usando Microsoft.Extensions.Configuration;' esista in 'Startup.cs' e che' project.json' contenga abbastanza '' "dipendenze" 'rapportate a FF7. Ad esempio: ["EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final"] (https://www.nuget.org/packages/EntityFramework.MicrosoftSqlServer/7.0.0-rc1-final) e ["EntityFramework. Comandi ":" 7.0.0-rc1-final "] (https://www.nuget.org/packages/EntityFramework.Commands/7.0.0-rc1-final). – Oleg

+0

@ Dblock247: Ho giocato un po 'e penso che dovresti semplicemente aggiungere 'using Microsoft.Data.Entity;' a 'Startup.cs'. – Oleg

2

È necessario pubblicare il numero project.json.

Riferimento System.Data e la rimozione di dnxcore50 in project.json mi permette di compilare il codice di cui sopra:

"frameworks": { 
    "dnx451": { 
     "frameworkAssemblies": { 
      "System.Data": "4.0.0.0" 
     } 
    } 
} 
+0

grazie per il vostro aiuto – Dblock247