Entity Framework Core 2 – スカラー関数のマッピング

エンティティ フレームワーク コア 2 8月14日に発売されました。新しい機能をもたらしました。

この記事では、そのうちの 1 つを説明します:スカラー関数のマッピング
ついに! SQL SERVER を使用できます のスカラー関数 エンティティへの LINQ !

仕組みは?

これらは静的に宣言する必要があり、受信/送信パラメータを正確に尊重する必要があります。
また、静的メソッドで DbFunction という名前の属性を宣言する必要があります。 これは、スカラー関数の名前とそれが属するスキーマをパラメーターとして受け取ります。

例:

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

Microsoft の例では、このメソッドを DbContext に実装しました たとえば、

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);
   }
}

この静的メソッドは、次のように別の場所に確実に実装できます:

  • 古典的な静的クラス内の静的メソッド
  • スカラー関数が使用する対象エンティティの拡張メソッド

例:

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();
    }
}

これら 3 つのシナリオの使用法:

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();
}

いい機能ですよね? 😉