.Net Core如何实现SQLAdapter ./ DataTable函数

时间:2016-07-27 08:38:03

标签: c# datatable .net-core

我有一个简单的.Net Framework例程,它运行一个查询并返回一个DataTable对象。我需要将其移植到.Net Core,但我推断不支持SQLAdapter和DataTable

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;

有人可以建议我如何使用支持的内容重新实现此代码吗? 感谢

4 个答案:

答案 0 :(得分:20)

现在支持

SqlDBAdapterDataTable

您必须使用VS2017 Preview 15.3,目标.net核心2.0,并为System.Data.CommonSystem.Data.SqlClient添加NuGet包。代码如下。

有关详细信息,请参阅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;
}

答案 1 :(得分:9)

UPDATE:这个答案对应于.NET Core 1.x(这是我写这篇文章时的最新版本)。 如果您使用的是.NET Core 2.x(截至2017年7月的测试版),请查看Joe的答案。

原始回答:

推荐阅读:Porting to .NET Core

我引用:

  
      
  • System.Data 即可。虽然基础层已经是.NET Core的一部分,即提供者模型和SQL客户端,但目前还没有一些功能,例如架构支持和DataTable / DataSet。
  •   

您可以使用SqlDataReader但不能使用SqlAdapter或DataTable。

首先添加System.Data.SqlClient NuGet包。

然后你可以......

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

IList<Dictionary<string, object>>适合您吗?

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

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

现在您可以使用results[0]["FirstName"].ToString()

阅读

除非你想切换到Entity Framework Core,否则这个tutorial很方便。

答案 2 :(得分:6)

您可以使用现有的.NET Core DAL库代替DataAdapter / DataTable,它支持通过低级ADO.NET接口进行CRUD操作。最近我发布了NReco.Data:独立于提供者的DAL,它支持自动生成SQL语句,抽象查询和简单记录CRUD操作。

例如,问题中的代码段可以通过以下方式重新实现:

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

复杂的SQL查询可以作为应用程序级数据视图执行:

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并没有尝试用自己的Query 替换 SQL(就像LINQ一样);而不是它允许您从业务逻辑中进行简单的独立于数据库的查询 并使用特殊的应用程序级数据视图封装复杂的SQL语法,这些数据视图可以像只读表一样访问。

还可以直接使用Select方法重载指定原始SQL查询(如EF Core中的FromSql):

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

答案 3 :(得分:1)

您可以使用DbDataAdapter链接获取更多信息

然后将此功能用于CreateDataAdapter

private static DbDataAdapter CreateDataAdapter(this DbConnection connection, DbCommand command)
{
     var adp = DbProviderFactories.GetFactory(connection).CreateDataAdapter();
     adp.SelectCommand = command;
     return adp;
 }

那么正常人可以使用下面的类似代码

var connection = Context.Database.GetDbConnection();
using var command = connection.CreateCommand();
command.CommandText = cmdText;
using DbDataAdapter adp = connection.CreateDataAdapter(command);

可以填写

using DataSet dataSet = new DataSet();
adp.Fill(dataSet);