How popular is a model from a DataReader in C #?

6

Sorry for ignoring this question. In PHP there was the possibility of using the "FetchClass" of the PDO that took all the results of a table and threw them into an object of a certain class, but I did not find anything similar in C #.

By the DataReader I would have to get each property and play in the model manually, what I wanted to do is make it automatic, since the table names are the same as the model.

At the moment I found the Entity Framework very advanced and would like to understand some lower .NET concepts before proceeding.

Would a model be popular from a DataReader or DataSet?

    
asked by anonymous 09.08.2017 / 05:54

2 answers

5

No. Automatically can not.

One option is to use a little reflection and do this job. I will not post an answer with this because I do not think the intent of this question, mainly because of this part

  

At the moment I found the Entity Framework very advanced and would like to understand some lower .NET concepts before proceeding.

What you can do is create a method that accepts a IDataRecord and returns an instance of the template.

As for example:

public class Pessoa
{
    public int Id { get; set; }
    public string Nome { get; set; }

    public Pessoa Criar(IDataRecord record)
    {            
        return new Pessoa
        {
           Id = record["id"],
           Nome = record["nome"]
        };
    }
}

From this, you can create a generic method that reads DataReader and returns a collection of data.

public IEnumerable<T> LerDados<T>(IDataReader reader, Func<IDataRecord, T> CriarObj)
{
    try
    {
        while (reader.Read())
        {
            yield return CriarObj(reader);
        }
    }
    finally
    {
         reader.Dispose();
    }
}

The use would be something like this

var pessoas = LerDados(dataReader, Pessoa.Criar);
    
09.08.2017 / 14:33
0

As the LINQ user responded, it is not directly possible.

However using Aline's suggestion to use an ORM I found the package "Dapper" and "Dapper.Contrib", which are extremely simple and do not require many configurations. To map the objects is great, even if you do not like using an ORM, since it allows you to use your queries in the traditional way.

Example usage:

public class Cidade
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public string Uf { get; set; }
    public int Ativo { get; set; }
}

And here is where we map the result of any Query (example).

List<Cidade> listCidades;
Cidade model = new Cidade { Nome = "São Paulo" };

using (MySqlConnection con = new MySqlConnection(Config.GetConString()))
{
    con.Open();

    var cidades = con.Query<Cidade>
    (
        "SELECT * FROM cidades WHERE nome LIKE @nome",

        new
        {
            nome = "%" + model.Nome + "%"
        }
    );

    listCidades = cidades.ToList<Cidade>();

    con.Close();
}

For simpler queries to insert, update, delete, you can use Dapper extensions.

T Get<T>(id);
IEnumerable<T> GetAll<T>();
int Insert<T>(T obj);
int Insert<T>(Enumerable<T> list);
bool Update<T>(T obj);
bool Update<T>(Enumerable<T> list);
bool Delete<T>(T obj);
bool Delete<T>(Enumerable<T> list);
bool DeleteAll<T>();

In this example I used MySQL and Dapper worked perfectly.

You can also use the Repository pattern to group these queries into their proper classes and save generic operations using a generic repository.

public abstract class RepositoryBase<T> where T : class
{
    protected MySqlConnection con;

    protected int timeout;

    public RepositoryBase(MySqlConnection con, int timeout = 10)
    {
        this.con = con;
        this.timeout = timeout;
    }

    public long Insert(T model)
    {
        return con.Insert<T>(model);
    }

    public bool Update(T model)
    {
        return con.Update<T>(model);
    }

    public bool Delete(T model)
    {
        return con.Delete<T>(model);
    }
}

And for the child classes.

public class CidadesRepository : RepositoryBase<Cidade>
{
    public CidadesRepository(MySqlConnection con, int timeout = 10) : base(con, timeout) {}

    public List<Cidade> Search(Cidade model)
    {

        var cidades = con.Query<Cidade>
        (
            "SELECT * FROM cidades WHERE nome LIKE @nome OR uf LIKE @uf",

            new
            {
                nome = "%" + model.Nome + "%",
                uf = "%" + model.Uf + "%"
            }
        );

        return cidades.ToList<Cidade>();
    }
}

Note that after installing the packages via Nu-Get, you need to include the references in the code and in the project.

using Dapper;
using Dapper.Contrib.Extensions;
  

Dapper: link

    
14.08.2017 / 16:59