Asp.Net Core 項目 EntityFramework Core 根據登陸用戶名過濾數據

 一、建立ASP.NET Core Web Applicatoin (MVC)項目,而且使用 Individual User Accounthtml

 

 

 

 二、建立數據篩選接口 Models->IDataFilter.csgit

    public interface IDataFilter
    {
        string UserName { get; set; }
    }

三、建立實體 Models->Book.cs 並繼承 IDataFilter接口,並將實體加入到 Data->ApplicatoinDbContext.cs 上下文中.github

    public class Book : IDataFilter
    {
        public int Id { get; set; }
        [Display(Name = "書名")]
        public string Name { get; set; }
        public string UserName { get; set; }
    }
    public class ApplicationDbContext : IdentityDbContext
    {
        public DbSet<Book> Books { get; set; }
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
    }

四、利用模板建立Book類的 CRUD界面。在 Controllers文件夾上 右鍵 選擇 Add(新增)->Controller(控制器)數據庫

 

  

五、自動生成Book的增刪改查以後,咱們在這裏要作一個細微的修改,由於咱們IDataFilter字段 UserName是系統生成的,因此咱們要修改兩個地方瀏覽器

  將BooksController.cs 下的 Create Action(因爲只作演示,沒有去修改Update頁面)裏面的 Bind UserName去掉。修改後結果以下ide

   並將建立頁面 Views->Books->Create.cshtml 中的 UserName 部份備註ui

  

 

  在母版頁添加Book菜單連接 Views->Shared->_Layout.cshtmlthis

六、打開Nuget管理控制檯 遷移數據庫,並F5運行,點擊Book連接。檢查一下程序 有沒問題。spa

Add-Migration Init //建立遷移文件
Update-Database //更新到數據庫

七、因爲Book實體實現了IDataFilter,UserName咱們會經過重寫ApplicationDbContext的SaveChanges的實現,進行自動填充用戶名.因爲要獲取登陸信息,在ApplicationDbContext中咱們需注入 IHttpContextAccessor3d

 

    public class ApplicationDbContext : IdentityDbContext
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        public DbSet<Book> Books { get; set; }
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor)
            : base(options)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public override int SaveChanges()
        {
            FillDataFilterInfo();
            return base.SaveChanges();
        }
        public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            FillDataFilterInfo();
            return base.SaveChangesAsync(cancellationToken);
        }
        protected void FillDataFilterInfo() =>
            ChangeTracker
            .Entries()
            .Where(w => w.Entity is IDataFilter && w.State == EntityState.Added)
            .ToList()
            .ForEach(entry => ((IDataFilter)entry.Entity).UserName = CurrentUserName);

        private string CurrentUserName => _httpContextAccessor.HttpContext.User?.Identity?.Name;
    }

八、驗證結果,運行項目,首先註冊一個賬號。而後進行建立一本書。最終結果。

九、最後咱們來實現數據過濾部份代碼,打開 ApplicatonDbContex.cs

  添加私有方法DataFilters

        private void DataFilters<T>(ModelBuilder builder)
            where T : class
        {
            builder.Entity<T>().HasQueryFilter(s => ((IDataFilter)s).UserName == CurrentUserName);
        }

  添加一個靜態MethodInfo方法。這裏用到返射實現

        private static readonly MethodInfo _dataFiltersMethodInfo = typeof(ApplicationDbContext).GetMethod(nameof(DataFilters), BindingFlags.Instance | BindingFlags.NonPublic);

 

  在重寫OnModelCreating ,針對全部實現 IDataFilter的實體添加數據過濾

  

        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Model
                .GetEntityTypes()
                .Where(w => typeof(IDataFilter).IsAssignableFrom(w.ClrType))
                .ToList().ForEach(entityType =>
                {
                    _dataFiltersMethodInfo
                      .MakeGenericMethod(entityType.ClrType)
                      .Invoke(this, new object[] { builder });
                });
            base.OnModelCreating(builder);
        }

十、運行程序,分別用不一樣的瀏覽器。註冊兩個賬號。而後建立幾本書。最終結果

 

 

 

完結!第一次寫,見諒。

源碼地址:https://github.com/CC1027CC/DataFilter

相關文章
相關標籤/搜索