2016-07-27 26 views
13

Mam prostą procedurę .Net Framework, która uruchamia zapytanie i zwraca obiekt DataTable. Muszę do tego portu .NET Core jednak wnoszę, że SQLAdapter i DataTable nie są obsługiwane.NET Core, jak zaimplementować SQLAdapter ./ DataTable function

SqlConnection con = new SqlConnection(m_ConnectString); 
SqlCommand cmd = new SqlCommand(strQuery); 
SqlDataAdapter sda = new SqlDataAdapter(); 
// assign the transaction and connection to the command object 
cmd.Connection = con; 
sda.SelectCommand = cmd; 
DataTable dt = new DataTable(); 
// execute query and soak up results 
sda.Fill(dt); 
return dt; 

Może ktoś zasugerować jak mogę reimplement ten kod, za pomocą tego, co jest obsługiwane? Dzięki

+0

Cóż, można zacząć od spojrzenia na źródła odniesienia dla [SqlDataAdapter] (http://referencesource.microsoft.com/#System.Data/System/Data/SqlClient/SqlDataAdapter.cs) i [DataTable ] (http://referencesource.microsoft.com/#System.Data/System/Data/DataTable.cs) i ponownie zaimplementuj części, których faktycznie potrzebujesz ... także: powodzenia. – Corak

+0

Dziękuję za odpowiedź, ale nie wiem, jak bardzo to pomaga. Przyjąłem, że wielu innych dotknęłoby ten problem, i że nie wszyscy zamierzają go naprawić poprzez wdrożenie części ram. – Hughgo

+2

Cóż, jednym problemem jest to, że jeśli .Net Core nie wie o 'DataTable', to nie możesz' zwrócić dt' i wszystko inne, co działałoby z 'DataTable' nie będzie już działać. Pytanie brzmi więc, jakiej funkcjonalności "DataTable" naprawdę potrzebujesz i możesz użyć na przykład 'DataReadera' zamiast tego (jeśli' DataReader' jest dostępny w .Net Core, nigdy nie pracował z tym). – Corak

Odpowiedz

9

AKTUALIZACJA: Ta odpowiedź odpowiada .NET Core 1.x (która była najnowsza w czasie, kiedy to napisałem). Jeśli korzystasz z .NET Core 2.x (w wersji beta od lipca/2017 r.), Sprawdź odpowiedź Joe.

Oryginalny odpowiedź:

Zalecane przeczytać: Porting to .NET Core

cytuję:

  • System.Data. Podczas gdy warstwa podstawowa jest już częścią .NET Core, tj. Modelu dostawcy i klienta SQL, niektóre funkcje są obecnie niedostępne, takie jak obsługa schematów i DataTable/DataSet.

Można używać SqlDataReader ale nie SqlAdapter lub DataTable.

Zacznij od dodania pakietu NuGet System.Data.SqlClient.

Następnie można ...

var con = new SqlConnection("..."); 
var cmd = con.CreateCommand(); 
cmd.CommandText = "..."; 
var reader = cmd.ExecuteReader(); 
// populate your custom data structure 

Czy IList<Dictionary<string, object>> pracuje dla Ciebie?

var results = new List<Dictionary<string, object>>(); 

while (reader.Read()) 
{ 
    results.Add(Enumerable.Range(0, reader.FieldCount).ToDictionary(reader.GetName, reader.GetValue)); 
} 
return results; 

Więc teraz można odczytać za pomocą results[0]["FirstName"].ToString()

Jeśli nie chcesz, aby przełączyć się do Entity Framework Core w takim przypadku tutorial jest poręczny.

+0

Zamknij, ale bez cygara. – ProfK

+0

datowana odpowiedź. już nie poprawiam. –

+0

Dzięki, zaktualizowałem odpowiedź. Miło jest wiedzieć, że jest teraz obsługiwany. –

6

Zamiast DataAdapter/DataTable można użyć jednej z istniejących bibliotek DAL dla .NET Core, które obsługują operacje CRUD za pośrednictwem niskopoziomowych interfejsów ADO.NET. Niedawno opublikowałem NReco.Data: niezależny od dostawcy DAL, który obsługuje automatyczne generowanie instrukcji SQL, abstrakcyjne zapytania i proste operacje zapisu CRUD.

Na przykład fragment kodu z pytaniem może być przepisany w następujący sposób:

var con = new SqlConnection(m_ConnectString); 
var dbFactory = new NReco.Data.DbFactory(
    System.Data.SqlClient.SqlClientFactory.Instance); 
var dbCmdBuilder = new NReco.Data.DbCommandBuilder(dbFactory); 
var dbAdapter = new NReco.Data.DbDataAdapter(con, dbCmdBuilder); 

var selectRecordsList = dbAdapter.Select( 
    new Query("some_table")).ToList<Dictionary<string,object>>(); 

złożonych zapytań SQL mogą być wykonywane jako widoków danych na poziomie aplikacji:

dbCmdBuilder.Views["some_view"] = new DbDataView(
    @"SELECT @columns FROM Employee emp 
     LEFT JOIN Company c ON (c.Id=emp.CompanyId) 
     @where[ WHERE {0}] @orderby[ ORDER BY {0}] 
    ") { 
     FieldMapping = new Dictionary<string,string>() { 
     {"Id", "emp.Id"}, 
     {"*", "emp.*, c.Title as CompanyTitle"} 
     } 
    }; 
var someViewRS = dbAdapter.Select(new Query("some_view")).ToRecordSet(); 

NReco.Data nie próbuje zamieniać SQL z własnym zapytaniem (jak robi LINQ); zamiast tego pozwala tworzyć proste zapytania niezależne od bazy danych z logiki biznesowej i zawierać złożoną składnię SQL ze specjalnymi widokami danych na poziomie aplikacji, które są dostępne jak tabele tylko do odczytu.

Ponadto jest możliwe określenie zapytań SQL surowego bezpośrednio Select metodą przeciążenia (jak FromSql EF rdzenia):

var userModels = dbAdapter.Select("select * from users where id={0}", 5).ToList<User>(); 
+0

Dzięki za wszystkie odpowiedzi. Użyłem DataReadera i lekkiej tabeli danych (która jest w zasadzie listą list). – Hughgo

+0

@Hughgo przy użyciu DataReadera to najprostsze (i najlepiej działające) rozwiązanie oczywiście :) Mam nadzieję, że wypróbujesz bibliotekę NRECo.Data przy okazji. Nie wahaj się ze mną skontaktować w przypadku jakichkolwiek pytań lub problemów. –

+0

Skąd wziął się taki projekt z ziemi, gdy obiekty zapytania są ograniczone do nazwanej tabeli? A co z dosłownie milionami przypadków poza kojcem, gdzie kwerenda źródła danych może być dynamicznym sql, lub łączeniem, itp.? – ProfK

14

SqlDBAdapter i DataTable obecnie obsługiwana.

Należy użyć podglądu VS2017 Preview 15.3, docelowego .net rdzenia 2.0 i dodać pakiety NuGet dla System.Data.Common, a także System.Data.SqlClient. Kod poniżej.

Aby uzyskać więcej informacji, patrz https://blogs.msdn.microsoft.com/devfish/2017/05/15/exploring-datatable-and-sqldbadapter-in-asp-net-core-2-0/.

public static DataTable ExecuteDataTable(SqlConnection conn, CommandType cmdType, string cmdText, SqlParameter[] cmdParms) 
{ 
    DataTable dt = new DataTable(); 
    dt.Columns.Add("CustomerID"); 
    dt.Columns.Add("CustomerName"); 
    SqlDataReader dr = ExecuteReader(conn, cmdType, cmdText, cmdParms); 
    while (dr.Read()) 
    { 
     dt.Rows.Add(dr[0], dr[1]); 
    } 
    return dt; 
} 

public static DataTable ExecuteDataTableSqlDA(SqlConnection conn, CommandType cmdType, string cmdText, SqlParameter[] cmdParms) 
{ 
    System.Data.DataTable dt = new DataTable(); 
    System.Data.SqlClient.SqlDataAdapter da = new SqlDataAdapter(cmdText, conn); 
    da.Fill(dt); 
    return dt; 
} 
+0

Nie użyłem VS2017 Preview 15.3, więc byłem nieświadomy tego rozwoju. – Fabulous

+0

Cieszę się, że to pomogło. –

+0

Od wersji VS2017 Preview 15.4 nadal wymaga to wstępnej wersji 'System.Data.SqlClient' – user3074376