Skip to content

DataAccess

El componente DataAccess contienen una lista de métodos que nos permiten relacionarnos con la base de datos. Para su utilización se recomienda agregar el siguiente método en el componente que ya utiliza DataAccessRegistry, lo cual nos facilitara el uso del mismo.

    /// <summary>
    /// Convenience method
    /// </summary>
    private IDataAccess DataAccess => _dataAccessRegistry.GetDataAccess();

CRUD (Create, Read, Update and Delete)

Como se menciono anteriormente, el micro-orm esta basado en Dapper, el cual no contienen de forma nativa toda la parte de Mapping que necesitamos para utilizar métodos CRUD, el componente DataAccess incorpora estos métodos utilizando la libreria Dapper-Extensions. A continuación se detallan los métodos CRUD que ofrece este componente:

    void Insert<T>(T entity) where T : class;
    void Update<T>(T entity) where T : class;
    void Delete<T>(T entity) where T : class;
    T Get<T>(object id) where T : class;
    IList<T> GetAll<T>() where T : class;
    IList<T> Select<T>(object predicate) where T : class;
    int Count<T>(object predicate, int? commandTimeout = null) where T : class;

Mapping

Para hacer uso de los mismos, deberemos agregar una clase de Mapping por cada entidad, ejemplo:

  public class Person
  {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateCreated { get; set; }
    public bool Active { get; set; }
    public IEnumerable<Phone> Phones { get; private set; }
  }

  public class Phone
  {
    public int Id { get; set; }
    public string Value { get; set; }
  }

  public class PersonMapper : ClassMapper<Person>
  {
    public PersonMapper()
    {
      Table("Person");
      Map(c => c.Id).Key(KeyType.Assigned);
      Map(m => m.Phones).Ignore();
      Map(m => m.DateCreated).Column("Created_Date");
      AutoMap();
    }
  }
Y agregar el nombre del assembly en donde tenemos las clases de Mapping (Generalmente es el mismo assembly) a la lista el la configuracion del DataAccessRegistry en la opción MappersAssemblies.

Query Methods

Tambien contamos con métodos para la ejecución de queries, los cuales son extensiones de los métodos nativos de Dapper y la documentacion aplica para estos metodos.

    void QueryMultiple(string sql, Action<GridReader> map, object param = null);
    IEnumerable<TReturn> Query<TReturn>(string sql, object param = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null);
    void ExecuteNonQuery(string sql, object param = null, CommandType? commandType = null);
    TResult ExecuteScalar<TResult>(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null);  

Many-To-Many

Imaginemos el siguiente escenario en donde tenemos una entidad Tracking que a su vez tiene una lista de la entidad Novedad:

  public class Tracking
  {
    public int Id { get; set; }
    public string Estado { get; set; }
    public IList<Novedad> Novedades { get; set; }
  }

  public class Novedad
  {
    public int Id { get; set; }
    public string Evento { get; set; }
    public int Tracking_Id { get; set; }
  }
Y necesitamos obtener de la base de datos una lista de Trackings y que cada Tracking a su vez tenga su lista de Novedades, para resolver esto podemos utilizar el metodo QueryMultiple y dentro del mismo podemos hacer uso del metodo extendido Lookup (namespace Infrastructure.Data) de la siguiente manera:

    string sql = @"SELECT t.*, n.* FROM tracking t LEFT JOIN novedad n on n.tracking_id = t.id where t.id < 2319960";
    IEnumerable<Tracking> trackings = default(IEnumerable<Tracking>);
    DataAccess.QueryMultiple(sql, reader =>
    {
      trackings = reader.Lookup<Tracking, Novedad, int>(t => t.Id, t =>
      {
        t.Novedades = t.Novedades ?? new List<Novedad>();
        return t.Novedades;
      });
    });
El método QueryMultiple tiene 2 argumentos, el primero es la query en donde obtendremos la lista de trackings y las novedades para cada tracking, y el segundo argumento es un Action<GridReader> en donde podremos implementar una lógica para mapear el resultado. En esta función es donde podemos utilizar el metodo Lookup<TMain, TSecond, TKey>, en donde deberemos especificar el tipo de la entidad principal, el tipo de la colleccion de la entidad principal, y el tipo del identificador de la entidad principal, luego como parametro tenemos 2 funciones: * En la primera Func<TMain, TKey> lookupId recibiremos como parámetro la entidad principal y deberemos devolver el identificador unico de esta entidad. En nuestro caso es la propiedad id del tracking. * La segunda Func<TMain, IList<TSecond>> lookupSecond es una función en donde recibiremos como parámetro la entidad principal y deberemos devolver la lista destino en donde almacenaremos cada una de las novedades. (En en ejemplo a no poder asegurar que la lista no sea nula al momento de crear el tracking, realizamos una inicializacion de la misma en caso de ser necesario)

Luego de la ejecución el método Lookup nos retornara la lista de tracking con sus respectivas novedades.