Entity Framework Core 2 – Mappatura delle funzioni scalari

Entity Framework Core 2 – Mappatura delle funzioni scalari

Entity Framework Core 2 è stato rilasciato il 14 agosto. Ha portato nuove funzionalità.

In questo articolo ne spiegherò uno:Mappatura delle funzioni scalari
Finalmente! possiamo usare SQL SERVER 's Funzione scalare in LINQ to Entities !

Come funziona?

Devono essere dichiarati staticamente, e devono rispettare esattamente i parametri in entrata/in uscita.
Devi inoltre dichiarare sul metodo statico un attributo denominato DbFunction che prende in parametro il nome della funzione scalare e il suo schema a cui appartiene.

Esempio :

[DbFunction("ufnGetStock", "dbo")]
 public static int GetProductStock(int productId)
 {
    throw new NotImplementedException();
 }

Microsoft nei suoi esempi ha implementato questo metodo nel DbContext che dà ad esempio:

public class AdventureWorksContext : DbContext
{
   public virtual DbSet<Product> Products { get; set; }

   [DbFunction("ufnGetStock", "dbo")]
   public static int GetProductStock(int productId)
   {
      throw new NotImplementedException();
   }

   protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
   {
      optionsBuilder.UseSqlServer(@const.connectionString);

      var lf = new LoggerFactory();
      lf.AddProvider(new MyLoggerProvider());
      optionsBuilder.UseLoggerFactory(lf);
    }

   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
      modelBuilder.HasDefaultSchema("Production");
      modelBuilder.ApplyConfiguration(new ProductConfiguration());
      base.OnModelCreating(modelBuilder);
   }
}

Puoi sicuramente implementare questo metodo statico altrove come :

  • Un metodo statico all'interno di una classe statica classica
  • Un metodo di estensione sull'entità target con cui lavora la funzione scalare

Esempi:

public static class ScalarFunctionsHelpers
{
   [DbFunction("ufnGetStock", "dbo")]
    public static int GetProductStock(int productId)
    {
       throw new NotImplementedException();
    }
}

public static class ScalarFunctionsExtentions
{
   [DbFunction("ufnGetStock", "dbo")]
    public static int GetProductStock(this Product product, int productId)
    {
       throw new NotImplementedException();
    }
}

Utilizzo di questi 3 scenari:

public int GetProductStock(int productId)
{
   // DbContext example
   var query = _context.Products
   .Where(x => x.ProductID == productId)
   .Select(d => AdventureWorksContextDI.GetProductStock(d.ProductID));

   // Exemple of externalized in static class as static function
   query = _context.Products
   .Where(x => x.ProductID == productId)
   .Select(d=> ScalarFunctionsHelpers.GetProductStock(d.ProductID));

   // Exemple of externalized in static class as extension method
   query = _context.Products
   .Where(x => x.ProductID == productId)
   .Select(d => d.GetProductStock(d.ProductID));

   return query.FirstOrDefault();
}

Bella caratteristica vero? 😉