上次对EntityFramework.DynamicFilters整体的项目结构有了一个认识,这次我们就通过阅读说明文档,示例项目,和单元测试,来动手构建一个我们的体验项目,通过对动态过滤器的使用,使得我们对过滤功能,在心理上有一个感性的认识,然后再一块深入学习代码内部的机理。

首先,我们来看一下项目说明文档,项目的文档结构说明如下

  

这是开源项目基础内容

  1. CHANGELOG: 一个修改日志,为什么会有修改日志,是对历史发布版本内容的记录,也方便其他使用者,看到修改日志,知道修改了哪些功能,对自己当前的版本有什么影响,要不要升级,等问题.下面是修改日志的内容:

2.LICENSE:这个是做什么用的,打开看的时候,里面是什么法律责任,侵权等问题,去网上查了一下, 在开源项目创建时,还是得仔细考虑一下该用哪种License。要是以后你的项目火了,你就不会因为当初License没选对,而哑巴吃黄连——有苦说不出了。

特别说一下,很多新手(就像我)可能根本没有为自己的项目选择License。没有为项目选择License,意味着他人不能对你的项目进行散发、改动。但他人可以以个人的名义使或以商业用途使用你的软件。另外,如果你将没有License的项目传到了Github上,你就默认接受了Github的服务条款协议——别的用户可以查看或者fork你的项目。

这个网站介绍了各种license的区别:https://choosealicense.com/licenses/

3.Readme.md:第一次打开这个文档是下面这个样子的

去网上找了一下,那么md后缀的文件到底是个什么鬼呢,看这里:

http://www.kuqin.com/shuoit/20141125/343459.html

怎么打开呢,我在vs2015扩展里面,安装了一个插件:

再打开文档的时候,就是这个样子:

左边可以编辑,右边马上就显示了编辑的效果,确实不错

README 应该是介绍code source 的一个概览.其实这个静态文件是有约定成俗的规范.

1.项目介绍

2.代码实现了什么功能?

3.该如何使用? (系统环境参数,部署要素)

4.代码组织架构是什么样的?

5.版本更新重要摘要

如果你的README包括上面的内容,那么当使用者拿到代码,打开README后,基本就知道该如何下手了

下面是创建的体验项目:

第一步:新建控制台应用程序

第二步:通过nuget包管理器,引用:

1.EntityFramework 6.1.2

2.EntityFramework.DynamicFilters.2.6.0

第三步:添加dbContext,model

添加DemoContext:

  1. public class DemoContext: DbContext
  2. {
  3. public static Guid CurrentAccountID { get; set; }
  4. public DbSet<Account> Accounts { get; set; }
  5. public DbSet<BlogEntry> BlogEntries { get; set; }
  6.  
  7. public DemoContext()
  8. {
  9. Database.SetInitializer(new ContentInitializer<DemoContext>());
  10. Database.Log = log => System.Diagnostics.Debug.WriteLine(log);
  11. Database.Initialize(false);
  12. }
  13.  
  14. protected override void OnModelCreating(DbModelBuilder modelBuilder)
  15. {
  16. base.OnModelCreating(modelBuilder);
  17. }
  18. }
  19.  
  20. public class ContentInitializer<T> : DropCreateDatabaseAlways<T>
  21. where T : DemoContext
  22. {
  23. protected override void Seed(T context)
  24. {
  25. System.Diagnostics.Debug.Print("Seeding db");
  26.  
  27. // Seeds 2 accounts with 9 blog entries, 4 of which are deleted
  28.  
  29. var homer = new Account
  30. {
  31. UserName = "homer",
  32. BlogEntries = new List<BlogEntry>
  33. {
  34. new BlogEntry { Body="Homer's first blog entry", IsDeleted=false, IsActive=true, StringValue=""},
  35. new BlogEntry { Body="Homer's second blog entry", IsDeleted=false, IsActive=true, StringValue=""},
  36. new BlogEntry { Body="Homer's third blog entry (deleted)", IsDeleted=true, IsActive=true, StringValue=""},
  37. new BlogEntry { Body="Homer's fourth blog entry (deleted)", IsDeleted=true, IsActive=true, StringValue=""},
  38. new BlogEntry { Body="Homer's 5th blog entry (inactive)", IsDeleted=false, IsActive=false, StringValue=""},
  39. new BlogEntry { Body="Homer's 6th blog entry (deleted and inactive)", IsDeleted=true, IsActive=false, StringValue=""},
  40. }
  41. };
  42. context.Accounts.Add(homer);
  43.  
  44. var bart = new Account
  45. {
  46. UserName = "bart",
  47. BlogEntries = new List<BlogEntry>
  48. {
  49. new BlogEntry { Body="Bart's first blog entry", IsDeleted=false, IsActive=true, StringValue=""},
  50. new BlogEntry { Body="Bart's second blog entry", IsDeleted=false, IsActive=true, StringValue=""},
  51. new BlogEntry { Body="Bart's third blog entry", IsDeleted=false, IsActive=true, StringValue=""},
  52. new BlogEntry { Body="Bart's fourth blog entry (deleted)", IsDeleted=true, IsActive=true, StringValue=""},
  53. new BlogEntry { Body="Bart's fifth blog entry (deleted)", IsDeleted=true, IsActive=true, StringValue=""},
  54. new BlogEntry { Body="Bart's 6th blog entry (inactive)", IsDeleted=false, IsActive=false, StringValue=""},
  55. new BlogEntry { Body="Bart's 7th blog entry (deleted and inactive)", IsDeleted=true, IsActive=false, StringValue=""},
  56. }
  57. };
  58. context.Accounts.Add(bart);
  59.  
  60. context.SaveChanges();
  61. }
  62. }

添加两个实体:

  1. public class BlogEntry : ISoftDelete
  2. {
  3. [Key]
  4. [Required]
  5. [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  6. public Guid ID { get; set; }
  7.  
  8. public Account Account { get; set; }
  9. public Guid AccountID { get; set; }
  10.  
  11. public string Body { get; set; }
  12.  
  13. public bool IsDeleted { get; set; }
  14.  
  15. public int? IntValue { get; set; }
  16.  
  17. public string StringValue { get; set; }
  18. public DateTime? DateValue { get; set; }
  19.  
  20. public bool IsActive { get; set; }
  21. }
  22.  
  23. public interface ISoftDelete
  24. {
  25. bool IsDeleted { get; set; }
  26. }
  27.  
  28. public class Account
  29. {
  30. [Key]
  31. [Required]
  32. [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  33. public Guid ID { get; set; }
  34.  
  35. public string UserName { get; set; }
  36.  
  37. public ICollection<BlogEntry> BlogEntries { get; set; }
  38.  
  39. /// <summary>
  40. /// Column used to verify handling of Entity properties mapped to different conceptual property names.
  41. /// </summary>
  42. [Column("RemappedDBProp")]
  43. public bool RemappedEntityProp { get; set; }
  44. }

第四步:重写dbcontext里面 protected override void OnModelCreating(DbModelBuilder modelBuilder) 构建动态过渡器

  1. protected override void OnModelCreating(DbModelBuilder modelBuilder)
  2. {
  3. base.OnModelCreating(modelBuilder);
  4. modelBuilder.Filter("BlogEntryFilter", (BlogEntry b, Guid accountID, bool isDeleted) => (b.AccountID == accountID) && (b.IsDeleted == isDeleted),
  5. () => CurrentAccountID, () => false);
  6. }

构造了一个过滤器,自动添加条件,查询数据没有被软件删除,且只属于当前登录用户的数据。

调用

  1. var demoContext = new demo.DemoContext();
  2. var allBlogEntries = demoContext.BlogEntries.ToList();
  3. foreach (BlogEntry blogEntry in allBlogEntries)
  4. {
  5. Console.WriteLine(blogEntry.Body);
  6. }

通过阅读:开源项目里面的reademe.md文档,简单的把这个动态过滤器,用到ef实体的自动查询上。

公司用的rafy,当时只是知道怎么用rafy的过滤条件,现在想想应该也跟这种方式差不多,像rafy的幽灵插件,只是rafy想根据条件,配置动态查询条件是否方便,之前都只是单独添加插件,确实没有考虑动态的问题,现在ef的这个动态过滤从全局控制确实挺方便的。

读EntityFramework.DynamicFilters源码_心得_示例演示02的更多相关文章

  1. 读EntityFramework.DynamicFilters源码_心得_设计思想_04

    前几次,我们从说明文档,示例,单元测试了解了怎么用这个动态过滤器,那么如果仅仅是为了实现目的,知道怎么用就可以完成相应的功能开发,但我还想了解的问题是 作者是怎么将动态过滤器与EF结合的 有哪些设计思 ...

  2. 读EntityFramework.DynamicFilters源码_心得_单元测试03

    上个星期我们只是显示了一个示例,怎么在EF的框架内,注入我们拓展的动态过滤器 第一步:安装EntityFramework.DynamicFilters 第二步:重写OnModelCreating方法 ...

  3. 读EntityFramework.DynamicFilters源码_心得_整体了解01

    前两天同事发给我一个连接地址:实体框架高级应用之动态过滤 EntityFramework DynamicFilters为什么会找到动态过滤的内容,是源于前段时间,我们想做一个个人blog 后端用.NE ...

  4. Zookeeper_阅读源码第一步_在 IDE 里启动 zkServer(集群版)

    上篇文章Zookeeper_阅读源码第一步_在 IDE 里启动 zkServer(单机版)讲了在 idea 里以单机的方式启动zookeeper,这篇介绍一下以集群的方式启动. 集群方式启动,才会真正 ...

  5. Java 源码学习线路————_先JDK工具包集合_再core包,也就是String、StringBuffer等_Java IO类库

    http://www.iteye.com/topic/1113732 原则网址 Java源码初接触 如果你进行过一年左右的开发,喜欢用eclipse的debug功能.好了,你现在就有阅读源码的技术基础 ...

  6. Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

    Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...

  7. 如何读懂Framework源码?如何从应用深入到Framework?

    如何读懂Framework源码? 首先,我也是一个应用层开发者,我想大部分有"如何读懂Framework源码?"这个疑问的,应该大都是应用层开发. 那对于我们来讲,读源码最大的问题 ...

  8. 读源码【读mybatis的源码的思路】

    ✿ 需要掌握的编译器知识 ★ 编译器为eclipse为例子 调试准备工作(步骤:Window -> Show View ->...): □ 打开调试断点Breakpoint: □ 打开变量 ...

  9. Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例

    概要 前一章,我们学习了HashMap.这一章,我们对Hashtable进行学习.我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable.第1部分 Ha ...

随机推荐

  1. [ActionSprit 3.0] FMS接收正在播放的视频中嵌入的描述性信息(onMetaData事件)

    package { import flash.display.MovieClip; import flash.net.NetConnection; import flash.events.NetSta ...

  2. docker-compose命令

    转自:https://www.jianshu.com/p/2217cfed29d7 先来看一份 docker-compose.yml 文件,不用管这是干嘛的,只是有个格式方便后文解说: version ...

  3. Sklearn,TensorFlow,keras模型保存与读取

    一.sklearn模型保存与读取 1.保存 from sklearn.externals import joblib from sklearn import svm X = [[0, 0], [1, ...

  4. [摸鱼]cdq分治 && 学习笔记

    待我玩会游戏整理下思绪(分明是想摸鱼 cdq分治是一种用于降维和处理对不同子区间有贡献的离线分治算法 对于常见的操作查询题目而言,时间总是有序的,而cdq分治则是耗费\(O(logq)\)的代价使动态 ...

  5. 通过遍历类向Aspose.cell模板中插入数据

    /// <summary> /// 遍历类所有字段 /// </summary> /// <param name="designer">aspo ...

  6. 关于CAS

    CAS就是Compare And Swap. CAS操作是在每一次做修改操作时,并不加锁,而是在修改时比较旧值是否有变化,如果旧值不变就执行修改,如果旧值有变,则修改失败. 使用sql表示就是 upd ...

  7. 转载 Python 操作 MySQL 的正确姿势 - 琉璃块

    Python 操作 MySQL 的正确姿势 收录待用,修改转载已取得腾讯云授权 作者 |邵建永 编辑 | 顾乡 使用Python进行MySQL的库主要有三个,Python-MySQL(更熟悉的名字可能 ...

  8. (转)Linux企业运维人员常用的150个命令分享

    Linux企业运维人员常用的150个命令分享 原文:http://www.jb51.net/article/127014.htm 本文将向大家介绍Linux企业运维人员常用的150个命令,如有不足之处 ...

  9. ps中的常用功能与技巧

    1.如何将多个png图片合成一个? 首先,打开ps,新建一个透明色画布,然后再将两张图片拖入(注意:回车拖入),然后再选中这三个图层,右键选择合并图层,最后快速导出为png即可. 2.如何快速找到ps ...

  10. springboot整合jsp踩坑

    springboot以其高效的开发效率越来越多的用在中小项目的开发,并且在分布式开发中的使用也很广泛,springboot官方推荐的前端框架却是thymeleaf,并且默认不支持jsp,而大部分jav ...