エンティティ フレームワーク コア 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(); }
いい機能ですよね? 😉