「Asp.Net Core 5.0 + EF Core 5.0 + SQLServer 2019」環境で開発していて、 EF Core 5.0 の FromSqlRaw()でストアドプロシージャからDbSet<> に一覧データを取得したあと、ExecuteSqlRaw()からストアドプロシージャで一覧データを更新し、
その後、FromSqlRaw()でストアドプロシージャからDbSet<> に一覧データを取得し直すと、更新したデータが反映されてなくハマった。
EF Core 5.0 はデフォルトで、エンティティの追跡機能が有効になっていて、 エンティティに対する変更をSaveChanges()でデータベースへ反映する実装にしていないのが原因だったが、追跡機能を無効にする方法もある。
ApplicationDbContext.cs に「ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking」を加え、EF Core 5.0 の追跡機能を無効にすることで解消した。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; } // mst public DbSet<T_StockModel> DbSet_T_StockModel { get; set; } public DbSet<T_UserModel> DbSet_T_UserModel { get; set; } } |
SQLを全てストアドプロシージャで実装している環境では、EF Core 5.0 の追跡機能を有効にするメリットは何も無いので、無効にしておいた方が良い。
追跡機能を無効にすると、EF Core 5.0 のパフォーマンスが改善する。
当初、Dapperとパフォーマンスを比較し、Dapperの方が明らかにパフォーマンスが良かったが、 EF Core 5.0 の追跡機能を無効にした結果、パフォーマンスの差も解消した。
更新処理。
「Asp.Net Core 5.0 + EF Core 5.0」からストアドプロシージャを通してSQLServer 2019 上のデータを更新している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
using System.Collections.Generic; using System.Linq; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; public static void spUser_Update(ApplicationDbContext dbContext, int 更新ユーザNo, T_UserModel t_UserModel) { dbContext.Database .ExecuteSqlRaw("EXECUTE usr.spUser_Update @更新ユーザNo, @ユーザNo, @ユーザID, @ユーザパスワード, @メールアドレス, @ユーザ名, @役割, @有効フラグ", new SqlParameter("@更新ユーザNo", t_UserModel.Id), new SqlParameter("@ユーザNo", t_UserModel.Id), new SqlParameter("@ユーザID", t_UserModel.ユーザID), new SqlParameter("@ユーザパスワード", t_UserModel.ユーザパスワード), new SqlParameter("@メールアドレス", t_UserModel.メールアドレス), new SqlParameter("@ユーザ名", t_UserModel.ユーザ名), new SqlParameter("@役割", t_UserModel.役割), new SqlParameter("@有効フラグ", t_UserModel.有効フラグ) ); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
CREATE PROCEDURE [usr].[spUser_Update] @更新ユーザNo int, @ユーザNo int, @ユーザID varchar(200), @ユーザパスワード varchar(200), @メールアドレス varchar(200), @ユーザ名 varchar(100), @役割 tinyint, @有効フラグ tinyint AS BEGIN UPDATE [usr].[tUser] SET [ユーザID] = @ユーザID ,[ユーザパスワード] = @ユーザパスワード ,[メールアドレス] = @メールアドレス ,[ユーザ名] = @ユーザ名 ,[役割] = @役割 ,[有効フラグ] = @有効フラグ ,[更新ユーザNo] = @更新ユーザNo ,[更新日時] = GETDATE() WHERE [ユーザNo] = @ユーザNo ; END GO |
検索処理、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using System.Collections.Generic; using System.Linq; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; public static List<T_UserModel> spUser_Select_有効無効(ApplicationDbContext dbContext, 有効無効 有効無効) { return dbContext.DbSet_T_UserModel .FromSqlRaw("EXECUTE usr.spUser_Select_有効無効 @有効無効", new SqlParameter("@有効無効", (byte)有効無効) ).ToList(); } |
1 2 3 4 5 6 7 |
public enum 有効無効 : byte { 無効 = 0, 有効 = 1, } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
CREATE PROCEDURE [usr].[spUser_Select_有効無効] @有効無効 tinyint AS BEGIN SET NOCOUNT ON; SELECT [ユーザNo] AS Id ,[ユーザID] ,[ユーザパスワード] ,[メールアドレス] ,[ユーザ名] ,[役割] ,[有効フラグ] ,[削除フラグ] ,[登録ユーザNo] ,[登録日時] ,[更新ユーザNo] ,[更新日時] FROM [usr].[tUser] WHERE [有効フラグ] = @有効無効 ; END |
コメント