ENTITY FRAMEWORK CORE 

DEEP

DIVE

WHOAMI

  • Rafael Almeida
  • Head Software Engineering At Stone Payments
  • Moro em Itabaiana/SE

RalmsDeveloper

ENTITY FRAMEWORK CORE

  • Versão Atual 3.1.2
  • Versão em Desenvolvimento 5.0

O que você pode esperar nessa apresentação?

  • Um pouco de arquitetura
  • Desempenho
  • Como realmente o EF funciona por baixo dos panos
  • Demos e Dicas / hands-on-code

O QUE É O EF?

  • Ele é escrito em C#

  • Não é uma continuidade do EF 6.x

  • Podemos usar LINQ(Consulta integrada a linguagem)

var talksList = new[] { "EF", "DDD", "ARQUITETURA" };
var talks = talksList
    .Where(p => p == "EF")
    .OrderBy(p => p)
    .Skip(1)
    .Take(1)
    .ToArray();

Essas consultas são executadas em memória

Expressions

Func<int, bool> maiorQue10 = i => i > 10;
Expression<Func<int, bool>> maiorQue10Expression = i => i > 10;
Func<int, bool> maiorQue10ExpressionCompilada = maiorQue10Expression.Compile();
var parametro1 = Expression.Parameter(typeof(int), "i");
 
Expression<Func<int, bool>> expressionLambda =
    Expression.Lambda<Func<int, bool>>(
        Expression.GreaterThan(
            parametro1,
            Expression.Constant(10)),
        parametro1);
 
var maiorQue10Lambda = expressionLambda.Compile();
new[] { 10, 11, 12 }.Where(maiorQue10);
new[] { 10, 11, 12 }.Where(maiorQue10ExpressionCompilada);
new[] { 10, 11, 12 }.Where(maiorQue10Lambda);

Mais um pouco de Expressions

Func<string, string> toLower = str => str.ToLower();

new[] { "Rafael", "Almeida" }.Select(p => toLower(p)).ToList();
/* Count = 2
    [0]: "rafael"
    [1]: "almeida"
*/
var parametro = Expression.Parameter(typeof(string), "str");
var toLower   = typeof(string).GetMethod("ToLower", Type.EmptyTypes);
var body      = Expression.Call(parametro, toLower);
var lambda    = Expression.Lambda<Func<string, string>>(body, parametro);
var compiledToLower = lambda.Compile();
new[] { "Rafael", "Almeida" }.Select(p => compiledToLower(p)).ToList();
/* Count = 2
    [0]: "rafael"
    [1]: "almeida"
*/

IQueryable

vs

IEnumerable

IEnumerable

 

IEnumerable<T>.Where(Func<T, bool> predicate)

IQueryable

 

IQueryable<T>.Where(Expression<Func<T, bool>> predicate)

Aqui é interpretado e otimizado em tempo de execução!!!

 

Entendo melhor...

 

var resultado = db
    .Livros
    .Where(p => p.Descricao == "EF Core")
    .OrderByDescending(p => p.Preco);

Traduz para o SQL

... Where(p => p.Descricao == "EF Core")
WHERE Descricao = 'EF CORE'

Expressão

Isso é uma expressão com um operador binário

p => p.Descricao == "EF Core"    // BinaryExpression

Compreendendo...

Anatomia BinaryExpression

Propriedade  O que é?
Left Expression
Right Expression
NodeType Equal, AndAlso, ......

ExpressionVisitor

O pipeline principal!

ExpressionVisitor

public class MeuVisitor : ExpressionVisitor
{
    public override Expression Visit(Expression node)
    {
        // Identificar a expressão e montar o comando SQL
        
        return base.Visit(node);
    }
}

ExpressionVisitor

public virtual Expression Process(Expression query)
{
    query = new EnumerableToQueryableMethodConvertingExpressionVisitor().Visit(query);
    query = new QueryMetadataExtractingExpressionVisitor(_queryCompilationContext).Visit(query);
    query = new AllAnyToContainsRewritingExpressionVisitor().Visit(query);
    query = new GroupJoinFlatteningExpressionVisitor().Visit(query);
    query = new NullCheckRemovingExpressionVisitor().Visit(query);
    query = new EntityEqualityRewritingExpressionVisitor(_queryCompilationContext).Rewrite(query);
    query = new SubqueryMemberPushdownExpressionVisitor().Visit(query);
    query = new NavigationExpandingExpressionVisitor(...).Expand(query);
    query = new FunctionPreprocessingExpressionVisitor().Visit(query);
    new EnumerableVerifyingExpressionVisitor().Visit(query);
 
    return query;
}

Obrigado!!!

 

https://ralms.io

Twitter: @ralmsdeveloper