【问题标题】:Is ADO.NET in .NET Core possible?.NET Core 中的 ADO.NET 可能吗?
【发布时间】:2016-11-25 10:19:42
【问题描述】:

大多数教程都是实体框架,在 .Net Core 项目中没有提到 Ado.Net。我有一个“遗留”数据库,因此不能选择 EF/“代码优先”方法。

对于 ADO.NET 连接,System.Data.SqlClient 是否可用于 ASP.NET Core 项目?

在我使用 .NET Framework 项目模板时可用,但在 .NET Core 项目中仍然可用吗?

【问题讨论】:

  • 你有没有尝试过在 .NET Core 项目中使用它?这似乎是最明显的第一项研究。
  • 我已经做了,我无法编译,因为“找不到 SqlDataAdapter”。显然 System.Data 在 .NET Core 项目中不可用。有两种选择:使用 Core Framework 的 Web 应用程序 .NET Core,以及使用 .NET Framework 的另一个 Web 应用程序 .NET Core。当我选择第一个时,我遇到了这个问题。
  • 好吧,如果不添加依赖项,它将无法使用 - 但您应该尝试查看是否有可以使用的 .NET Core 兼容依赖项...
  • 那么,我必须通过 NuGet 安装 System.Data.SqlClient 吗?
  • 嗯,通过 nuget 包,但不是通过 nuget 客户端...您可以在项目文件中将其表示为依赖项。

标签: asp.net asp.net-mvc ado.net


【解决方案1】:

现有的SqlConnection 和其他相关连接仍然存在于System.Data.SqlClient 命名空间中,使用完整的框架或.NET Core 应该可以按预期工作。

您只需要添加适当的引用和 using 语句来包含它,例如通过 System.Data.SqlClient 命名空间,如下面的 project.json 文件所示:

然后通过你习惯的语法调用它:

using(var connection = new SqlConnection("{your-connection-string}"))
{
      // Do work here
}

只要你有一个有效的连接字符串来连接你现有的旧数据库,你应该没问题。

关于 ORM 的使用

我还发现有些人在使用 Dapper,一个 Micro-ORM 替代实体框架,显然更灵活。它在那里 用它代替 ADO.NET 有什么好处?

这些 ORM(对象关系映射器)是方便且通常功能强大的工具,可以更轻松地将现有数据库数据映射到特定的类和对象,从而使它们更易于使用(而不是通过数据读取器进行迭代、解析您的每一行并手动构建每个对象)。

就性能而言,最终取决于您要对查询执行的操作。 ADO.NET 通常是最快的,因为它是与数据库的基本连接,但在某些情况下,Dapper 实际上可以击败它。实体框架虽然非常有用,但在性能上通常落后,仅仅是因为它是一个如此大的 ORM。

再说一遍 - 这最终取决于你在做什么,但所有这些都是可行的选择。

【讨论】:

  • 我不确定你的答案是什么,因为 Entity Framework 6 在内部使用 ADO.NET,而 EF Core 似乎使用它自己的“数据库提供程序”框架(如果我理解正确的话) - 似乎就像不必要的代码重复。
  • “遗留数据库”是什么意思?
  • @John 他的意思是问题描述为遗留数据库的数据库。我认为它只是意味着“预先存在的”,而不是与应用程序同步开发的。
  • 我的错。也许“预先存在”是一个更合适的术语。可以建议进行修改,但请记住 4 年前的问题。
【解决方案2】:

.NET Core 2.0 有 DataSet、DataTable 和 SQlDataAdapter。在https://blogs.msdn.microsoft.com/devfish/2017/05/15/exploring-datatable-and-sqldbadapter-in-asp-net-core-2-0/ 上查看我的回答。

下面的代码可以正常工作

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

【讨论】:

    【解决方案3】:

    正如 Joe Healy 在他的 answer 在 DotNet Core 2.0 中提到的,可以使用所有 System.Data 功能。

    添加 nugets:

    • Microsoft.Extensions.Configuration
    • Microsoft.Extensions.Configuration.Json -- 从 json 读取连接字符串
    • System.Data.Common
    • System.Data.SqlClient

    config.json 示例:

    {
      "connectionString": "your-db-connection-settings"
    }
    

    这是一个完整的控制台应用示例。

    class Program
    {
        static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("config.json", false)
                .Build();
    
            var connectionString = configuration.GetSection("connectionString").Value;
    
            if(string.IsNullOrEmpty(connectionString))
                throw new ArgumentException("No connection string in config.json");
    
            using (var conn = new SqlConnection(connectionString))
            {
                var sql = "SELECT * FROM ExampleTable";
                using (var cmd = new SqlCommand(sql, conn))
                {
                    using (var adapter = new SqlDataAdapter(cmd))
                    {
                        var resultTable = new DataTable();
                        adapter.Fill(resultTable);
                    }
                }
            }
        }
    }
    

    【讨论】:

    • 谢谢,它可以工作,不需要安装 System.Data.SqlClient,没有它也可以工作,特别是这个包需要安装标准框架,限制你在 un-windows 平台上传程序
    【解决方案4】:

    需要注意的是,.NET Core 2.0 之前的版本没有 DataSet、DataTable 和相关对象。但在 2.0 之前,它拥有 Connection、Command、Parameter、DataReader 等相关对象的所有核心功能。

    您可以使用以下调用来简化通过 SQL Server 数据库提供程序与 SQL Server 的连接。

    public class BaseDataAccess
    {
        protected string ConnectionString { get; set; }
    
        public BaseDataAccess()
        {
        }
    
        public BaseDataAccess(string connectionString)
        {
            this.ConnectionString = connectionString;
        }
    
        private SqlConnection GetConnection()
        {
            SqlConnection connection = new SqlConnection(this.ConnectionString);
            if (connection.State != ConnectionState.Open)
                connection.Open();
            return connection;
        }
    
        protected DbCommand GetCommand(DbConnection connection, string commandText, CommandType commandType)
        {
            SqlCommand command = new SqlCommand(commandText, connection as SqlConnection);
            command.CommandType = commandType;
            return command;
        }
    
        protected SqlParameter GetParameter(string parameter, object value)
        {
            SqlParameter parameterObject = new SqlParameter(parameter, value != null ? value : DBNull.Value);
            parameterObject.Direction = ParameterDirection.Input;
            return parameterObject;
        }
    
        protected SqlParameter GetParameterOut(string parameter, SqlDbType type, object value = null, ParameterDirection parameterDirection = ParameterDirection.InputOutput)
        {
            SqlParameter parameterObject = new SqlParameter(parameter, type); ;
    
            if (type == SqlDbType.NVarChar || type == SqlDbType.VarChar || type == SqlDbType.NText || type == SqlDbType.Text)
            {
                parameterObject.Size = -1;
            }
    
            parameterObject.Direction = parameterDirection;
    
            if (value != null)
            {
                parameterObject.Value = value;
            }
            else
            {
                parameterObject.Value = DBNull.Value;
            }
    
            return parameterObject;
        }
    
        protected int ExecuteNonQuery(string procedureName, List<DbParameter> parameters, CommandType commandType = CommandType.StoredProcedure)
        {
            int returnValue = -1;
    
            try
            {
                using (SqlConnection connection = this.GetConnection())
                {
                    DbCommand cmd = this.GetCommand(connection, procedureName, commandType);
    
                    if (parameters != null && parameters.Count > 0)
                    {
                        cmd.Parameters.AddRange(parameters.ToArray());
                    }
    
                    returnValue = cmd.ExecuteNonQuery();
                }
            }
            catch (Exception ex)
            {
                //LogException("Failed to ExecuteNonQuery for " + procedureName, ex, parameters);
                throw;
            }
    
            return returnValue;
        }
    
        protected object ExecuteScalar(string procedureName, List<SqlParameter> parameters)
        {
            object returnValue = null;
    
            try
            {
                using (DbConnection connection = this.GetConnection())
                {
                    DbCommand cmd = this.GetCommand(connection, procedureName, CommandType.StoredProcedure);
    
                    if (parameters != null && parameters.Count > 0)
                    {
                        cmd.Parameters.AddRange(parameters.ToArray());
                    }
    
                    returnValue = cmd.ExecuteScalar();
                }
            }
            catch (Exception ex)
            {
                //LogException("Failed to ExecuteScalar for " + procedureName, ex, parameters);
                throw;
            }
    
            return returnValue;
        }
    
        protected DbDataReader GetDataReader(string procedureName, List<DbParameter> parameters, CommandType commandType = CommandType.StoredProcedure)
        {
            DbDataReader ds;
    
            try
            {
                DbConnection connection = this.GetConnection();
                {
                    DbCommand cmd = this.GetCommand(connection, procedureName, commandType);
                    if (parameters != null && parameters.Count > 0)
                    {
                        cmd.Parameters.AddRange(parameters.ToArray());
                    }
    
                    ds = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                }
            }
            catch (Exception ex)
            {
                //LogException("Failed to GetDataReader for " + procedureName, ex, parameters);
                throw;
            }
    
            return ds;
        }
     }
    

    请参阅以下文章以获取更多详细信息和示例: http://www.ijz.today/2016/09/net-core-10-connecting-sql-server.html

    【讨论】:

      【解决方案5】:

      在 ADO.NET Core 中,我不使用 System.Data.SqlClient,但我使用 Microsoft.Data.SqlClient。 到现在为止,我可以使用我以前的所有编码!

      【讨论】:

        【解决方案6】:

        Mr_LinDowsMac

        你仍然可以使用 EF

        有一个工具叫scaffold-dbcontext

        它将根据遗留数据库结构为您创建“实体”部分类。

        您需要稍微考虑管理“实体”和它与其他代码分开创建的 dbcontext 类。 (该工具可以覆盖现有的类)。也许是一个模型项目?

        我已经在 .net core 中使用了这个用于 SQL SERVER 和 ORACLE 项目

        您将需要其他软件包:

        • 如果 SQL SERVER 选择 Microsoft 包
        • 如果 ORACLE 选择 ORACLE 包(即使它们是以前的 .net Core 版本)

        看到这个link

        【讨论】:

          猜你喜欢
          • 2021-08-23
          • 2018-05-15
          • 1970-01-01
          • 1970-01-01
          • 2020-04-22
          • 1970-01-01
          • 1970-01-01
          • 2017-04-18
          相关资源
          最近更新 更多