2015-12-21 44 views
5

Tworzę projekt MVC 6 i wolałbym używać klasycznego ADO.net w Entity Framework 7. Mówi jednak, że przestrzeni nazw nie można znaleźć zarówno dla DataTable, jak i SqlDataAdapter. Mam używane oświadczenie System.Data i System.Data.SqlClient. Dawka nie wskazuje na błąd, dopóki nie spróbuję zbudować projektu.Jaka jest alternatywa dla DataTable z ADO.NET pod MVC 6?

Myślę, że czytałem gdzieś, że te dwa przestrzenie nazw nie są zaimplementowane w nowej wersji. Jeśli tak, czy istnieje alternatywny sposób robienia tego lub czy brakuje mi zależności lub instrukcji? Kod

:

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

mój 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" ] 
    } 
} 

skończyło się próbując wiele różnych elementów, aby postarać się o to przestrzegane. Jeśli istnieją odniesienia do użytkowania, proszę dać mi znać.

Odpowiedz

4

Rozumiem problem, bo lubię się do wykorzystywania istniejących procedur przechowywanych i zapytań SQL dynamiczny w moim kodu C#. Tworzenie nowego obiektu dla każdego zapytania o użycie jakiegoś istniejącego obiektu z właściwymi do zniesienia wartościami do zapisywania nowych wyników zapytania nie jest dobrym pomysłem. Ponadto lubię używać Web API do dostarczania danych w formacie JSON do użycia w interfejsie napisanym w JavaScript.

Po drugiej stronie Entity Framework zawiera sposób wykonywania zapytania SQL w wierszu i zapisywania wyników w obiekcie bez użycia jednostek. Opublikowałem fragmenty kodu the answer, z których można korzystać. Przypominam wkrótce pomysł.

Należy dołączyć ciąg połączenia do pliku konfiguracyjnego aplikacji. Na przykład można utworzyć appsettings.json z

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

Następnie należy utworzyć manekina klasy kontekstu

public class MyDbContext : DbContext 
{ 
} 

bez jakiegokolwiek podmiotu. Będziesz używać urządzenia DbContext tylko do utrzymywania połączenia z bazą danych.

Następnie należy wpisać Startup.cs, która tworzy własność Configuration na podstawie treści "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"]); 
      }); 
    } 
    ... 
} 

Teraz masz MyDbContext wstrzykiwany i można go używać w kontekście można użyć

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

Osobiście wolę używać List<dynamic> i ExecuteReader/ExecuteReaderAsync zamiast DataTable (patrz kod z the answer) , ale to nie jest takie ważne.

+0

Dziękuję. To doprowadzi mnie do właściwej drogi. Jednak pojawia się błąd w pliku startup.cs w options.SqlServer (Configuration ["Data: MyDbConnectionString"]); mówi DbContextOptionBuilder id zdefiniowany w assaybly thats nie jest wymieniony Dziękuję. To doprowadzi mnie do właściwej drogi. Jednak pojawia się błąd w pliku startup.cs w options.SqlServer (Configuration ["Data: MyDbConnectionString"]); mówi DbContextOptionBuilder id zdefiniowany w assaybly thats nie jest wymieniony – Dblock247

+1

@ Dblock247: Nie ma za co! 'UseSqlServer' jest zdefiniowany w' EntityFramework.MicrosoftSqlServer'. Powinieneś sprawdzić, czy 'using Microsoft.Extensions.DependencyInjection;' i 'using Microsoft.Extensions.Configuration;' istnieje w 'Startup.cs', a że' project.json' zawiera wystarczającą "" zależność "' repated do FF7. Na przykład: ["EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final"] (https://www.nuget.org/packages/EntityFramework.MicrosoftSqlServer/7.0.0-rc1-final) i ["EntityFramework. Polecenia ":" 7.0.0-rc1-final "] (https://www.nuget.org/packages/EntityFramework.Commands/7.0.0-rc1-finale). – Oleg

+0

@ Dblock247: Grałem trochę i myślę, że powinieneś po prostu dodać 'using Microsoft.Data.Entity;' do 'Startup.cs'. – Oleg

2

Powinieneś opublikować swoją project.json.

Odwoływanie System.Data i usuwanie dnxcore50 w project.json pozwala mi skompilować powyższy kod:

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

dziękuję za pomoc – Dblock247