Entity Framework (6) Asesoramiento de optimización de rendimiento

.net c# entity-framework entity-framework-6 performance

Pregunta

Tengo una capa de acceso a datos ADO.Net en mi aplicación que utiliza ADO.Net básico junto con procedimientos almacenados CRUD (uno por operación, por ejemplo, Select_myTable, Insert_myTable). Como puede imaginar, en un sistema grande (como el nuestro), la cantidad de objetos de base de datos requeridos por la capa DA es bastante grande.

He estado estudiando la posibilidad de refactorizar las clases de capa en clases EF POCO. Me las arreglé para hacer esto, pero cuando intento una prueba de rendimiento, se vuelve bastante horrible. Usando la siguiente clase (crear objeto, establecer la clave en el valor deseado, llamar a dataselect), 100000 ejecuciones de carga de datos solo toman unos 47 segundos (solo hay un puñado de registros en la base de datos). Mientras que el método de Procesamiento almacenado toma alrededor de 7 segundos.

Estoy buscando consejos sobre cómo optimizar esto, como punto de nota, no puedo cambiar la funcionalidad expuesta de la capa, solo cómo implementa los métodos (es decir, no puedo pasar la responsabilidad de la propiedad del contexto a la capa BO)

Gracias

public class DAContext : DbContext
{
    public DAContext(DbConnection connection, DbTransaction trans)
        : base(connection, false)
    {
        this.Database.UseTransaction(trans);

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //Stop Pluralising the Object names for table names.
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        //Set any property ending in "Key" as a key type.
        modelBuilder.Properties().Where(prop => prop.Name.ToLower().EndsWith("key")).Configure(config => config.IsKey());

    }

    public DbSet<MyTable> MyTable{ get; set; }
}

public class MyTable : DataAccessBase
{

    #region Properties

    public int MyTableKey { get; set; }

    public string Name { get; set; }
    public string Description { get; set; }
    public bool Active { get; set; }
    public int CreatedBy { get; set; }
    public DateTime CreatedDate { get; set; }
    public int ModifiedBy { get; set; }
    public DateTime ModifiedDate { get; set; }

    #endregion

    #region constructors

    public MyTable()
    {
        //Set Default Values.
        Active = true;
        Name = string.Empty;
        CreatedDate = DateTime.MinValue;
        ModifiedDate = DateTime.MinValue;
    }

    #endregion

    #region Methods

    public override void DataSelect(System.Data.SqlClient.SqlConnection connection, System.Data.SqlClient.SqlTransaction transaction)
    {
        using (DAContext ctxt = new DAContext(connection, transaction))
        {

            var limitquery = from C in ctxt.MyTable
                             select C;


            //TODO: Sort the Query
            limitquery = FilterQuery(limitquery);

            var limit = limitquery.FirstOrDefault();

            if (limit != null)
            {
                this.Name = limit.Name;
                this.Description = limit.Description;
                this.Active = limit.Active;
                this.CreatedBy = limit.CreatedBy;
                this.CreatedDate = limit.CreatedDate;
                this.ModifiedBy = limit.ModifiedBy;
                this.ModifiedDate = limit.ModifiedDate;
            }
            else
            {
                throw new ObjectNotFoundException(string.Format("No MyTable with the specified Key ({0}) exists", this.MyTableKey));
            }
        }
    }

    private IQueryable<MyTable1> FilterQuery(IQueryable<MyTable1> limitQuery)
    {
        if (MyTableKey > 0) limitQuery = limitQuery.Where(C => C.MyTableKey == MyTableKey);
        if (!string.IsNullOrEmpty(Name)) limitQuery = limitQuery.Where(C => C.Name == Name);
        if (!string.IsNullOrEmpty(Description)) limitQuery = limitQuery.Where(C => C.Description == Description);
        if (Active) limitQuery = limitQuery.Where(C => C.Active == true);
        if (CreatedBy > 0) limitQuery = limitQuery.Where(C => C.CreatedBy == CreatedBy);
        if (ModifiedBy > 0) limitQuery = limitQuery.Where(C => C.ModifiedBy == ModifiedBy);
        if (CreatedDate > DateTime.MinValue) limitQuery = limitQuery.Where(C => C.CreatedDate == CreatedDate);
        if (ModifiedDate > DateTime.MinValue) limitQuery = limitQuery.Where(C => C.ModifiedDate == ModifiedDate);

        return limitQuery;
    }

    #endregion


}

Respuesta popular

Las selecciones son lentas con el seguimiento activado. Definitivamente debes desactivar el seguimiento y medir nuevamente.

Echa un vistazo a mis puntos de referencia.

http://netpl.blogspot.com/2013/05/yet-another-orm-micro-benchmark-part-23_15.html




Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué