Is ADO.NET in .NET Core possible?

asp.netasp.net Mvcado.net

asp.net Problem Overview


Most tutorials are Entity Framework with no mention of Ado.Net in .Net Core projects. I have a "legacy" database, so a EF/"Code-First" approach is not an option.

For ADO.NET connections, is the System.Data.SqlClient available to an ASP.NET Core project?

It is available when I use a .NET Framework project template but is it still available in a .NET Core project?

asp.net Solutions


Solution 1 - asp.net

The existing SqlConnection and other related connections still exists within the System.Data.SqlClient namespace and should work as expected using the full framework or .NET Core.

You'll just need to add the appropriate references and using statements to include it such as through the System.Data.SqlClient namespace as seen below in your project.json file :

enter image description here

and then call it via the syntax you are accustomed to :

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

So as long as you have a valid connection string to connect to your existing legacy database, you should be just fine.

Regarding ORM Usage

> I also found that some people are using Dapper, a Micro-ORM > replacement for Entity Framework, apparenty more flexible. It is there > any advantages of using it instead ADO.NET?

These ORMs (object-relational mappers) are handy and often powerful tools that can more easily map your existing database data to specific classes and objects, which can make them easier to use (as opposed to iterating through a data reader, parsing each of your rows and building each object manually).

As far as performance goes, it ultimately depends on what you are going to be doing with your queries. ADO.NET will generally be the fastest as it a bare-bones connection to the database, however in some scenarios Dapper can actually beat it out. Entity Framework, while very useful, generally trails behind in performance, simply because it is such a large ORM.

Again - it ultimately depends on what you are doing, but all are viable options.

Solution 2 - asp.net

.NET Core 2.0 has DataSet, DataTable and SQlDataAdapter. See my answer at https://blogs.msdn.microsoft.com/devfish/2017/05/15/exploring-datatable-and-sqldbadapter-in-asp-net-core-2-0/ .

Code below works fine

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

Solution 3 - asp.net

As Joe Healy mentioned in his answer in DotNet Core 2.0 it is possible to use all System.Data features.

Add nugets:

  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.Json -- to read connection string from json
  • System.Data.Common
  • System.Data.SqlClient

config.json example:

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

Here is a full console app example.

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

Solution 4 - asp.net

It is important to note that .NET Core does not have DataSet, DataTable and related objects prior to version 2.0. But before 2.0, it has all of core features like Connection, Command, Parameter, DataReader and other related objects.

You can use following calls to simplify connectivity to SQL Server through SQL Server Database Provider.

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

Please refer to following article for more details and examples: http://www.ijz.today/2016/09/net-core-10-connecting-sql-server.html

Solution 5 - asp.net

In ADO.NET Core I do NOT use System.Data.SqlClient but I use Microsoft.Data.SqlClient. Until now, I could use all my previous coding!.

Solution 6 - asp.net

Mr_LinDowsMac

you could still use EF

there is a tool called scaffold-dbcontext

It will create "entity" partial classes for you based on the legacy database structure.

You will need to give a little thought to management of the "entity"s and the dbcontext class that it creates separately from your other code. (the tool can override existing classes). Maybe a Model project?

I have used this in .net core for SQL SERVER and ORACLE projects

You will need other packages:

  • if SQL SERVER pick Microsoft packages
  • if ORACLE pick ORACLE packages (even it they a a previous .net Core version)

See this link

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMr_LinDowsMacView Question on Stackoverflow
Solution 1 - asp.netRion WilliamsView Answer on Stackoverflow
Solution 2 - asp.netJoe HealyView Answer on Stackoverflow
Solution 3 - asp.netalehaView Answer on Stackoverflow
Solution 4 - asp.netImran JavedView Answer on Stackoverflow
Solution 5 - asp.netRob LasscheView Answer on Stackoverflow
Solution 6 - asp.netGregJFView Answer on Stackoverflow