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

这是开源项目基础内容
- 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:
public class DemoContext: DbContext
{
public static Guid CurrentAccountID { get; set; }
public DbSet<Account> Accounts { get; set; }
public DbSet<BlogEntry> BlogEntries { get; set; } public DemoContext()
{
Database.SetInitializer(new ContentInitializer<DemoContext>());
Database.Log = log => System.Diagnostics.Debug.WriteLine(log);
Database.Initialize(false);
} protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
} public class ContentInitializer<T> : DropCreateDatabaseAlways<T>
where T : DemoContext
{
protected override void Seed(T context)
{
System.Diagnostics.Debug.Print("Seeding db"); // Seeds 2 accounts with 9 blog entries, 4 of which are deleted var homer = new Account
{
UserName = "homer",
BlogEntries = new List<BlogEntry>
{
new BlogEntry { Body="Homer's first blog entry", IsDeleted=false, IsActive=true, StringValue=""},
new BlogEntry { Body="Homer's second blog entry", IsDeleted=false, IsActive=true, StringValue=""},
new BlogEntry { Body="Homer's third blog entry (deleted)", IsDeleted=true, IsActive=true, StringValue=""},
new BlogEntry { Body="Homer's fourth blog entry (deleted)", IsDeleted=true, IsActive=true, StringValue=""},
new BlogEntry { Body="Homer's 5th blog entry (inactive)", IsDeleted=false, IsActive=false, StringValue=""},
new BlogEntry { Body="Homer's 6th blog entry (deleted and inactive)", IsDeleted=true, IsActive=false, StringValue=""},
}
};
context.Accounts.Add(homer); var bart = new Account
{
UserName = "bart",
BlogEntries = new List<BlogEntry>
{
new BlogEntry { Body="Bart's first blog entry", IsDeleted=false, IsActive=true, StringValue=""},
new BlogEntry { Body="Bart's second blog entry", IsDeleted=false, IsActive=true, StringValue=""},
new BlogEntry { Body="Bart's third blog entry", IsDeleted=false, IsActive=true, StringValue=""},
new BlogEntry { Body="Bart's fourth blog entry (deleted)", IsDeleted=true, IsActive=true, StringValue=""},
new BlogEntry { Body="Bart's fifth blog entry (deleted)", IsDeleted=true, IsActive=true, StringValue=""},
new BlogEntry { Body="Bart's 6th blog entry (inactive)", IsDeleted=false, IsActive=false, StringValue=""},
new BlogEntry { Body="Bart's 7th blog entry (deleted and inactive)", IsDeleted=true, IsActive=false, StringValue=""},
}
};
context.Accounts.Add(bart); context.SaveChanges();
}
}

添加两个实体:
public class BlogEntry : ISoftDelete
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; } public Account Account { get; set; }
public Guid AccountID { get; set; } public string Body { get; set; } public bool IsDeleted { get; set; } public int? IntValue { get; set; } public string StringValue { get; set; }
public DateTime? DateValue { get; set; } public bool IsActive { get; set; }
} public interface ISoftDelete
{
bool IsDeleted { get; set; }
} public class Account
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ID { get; set; } public string UserName { get; set; } public ICollection<BlogEntry> BlogEntries { get; set; } /// <summary>
/// Column used to verify handling of Entity properties mapped to different conceptual property names.
/// </summary>
[Column("RemappedDBProp")]
public bool RemappedEntityProp { get; set; }
}

第四步:重写dbcontext里面 protected override void OnModelCreating(DbModelBuilder modelBuilder) 构建动态过渡器
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Filter("BlogEntryFilter", (BlogEntry b, Guid accountID, bool isDeleted) => (b.AccountID == accountID) && (b.IsDeleted == isDeleted),
() => CurrentAccountID, () => false);
}
构造了一个过滤器,自动添加条件,查询数据没有被软件删除,且只属于当前登录用户的数据。
调用
var demoContext = new demo.DemoContext();
var allBlogEntries = demoContext.BlogEntries.ToList();
foreach (BlogEntry blogEntry in allBlogEntries)
{
Console.WriteLine(blogEntry.Body);
}
通过阅读:开源项目里面的reademe.md文档,简单的把这个动态过滤器,用到ef实体的自动查询上。
公司用的rafy,当时只是知道怎么用rafy的过滤条件,现在想想应该也跟这种方式差不多,像rafy的幽灵插件,只是rafy想根据条件,配置动态查询条件是否方便,之前都只是单独添加插件,确实没有考虑动态的问题,现在ef的这个动态过滤从全局控制确实挺方便的。
读EntityFramework.DynamicFilters源码_心得_示例演示02的更多相关文章
- 读EntityFramework.DynamicFilters源码_心得_设计思想_04
前几次,我们从说明文档,示例,单元测试了解了怎么用这个动态过滤器,那么如果仅仅是为了实现目的,知道怎么用就可以完成相应的功能开发,但我还想了解的问题是 作者是怎么将动态过滤器与EF结合的 有哪些设计思 ...
- 读EntityFramework.DynamicFilters源码_心得_单元测试03
上个星期我们只是显示了一个示例,怎么在EF的框架内,注入我们拓展的动态过滤器 第一步:安装EntityFramework.DynamicFilters 第二步:重写OnModelCreating方法 ...
- 读EntityFramework.DynamicFilters源码_心得_整体了解01
前两天同事发给我一个连接地址:实体框架高级应用之动态过滤 EntityFramework DynamicFilters为什么会找到动态过滤的内容,是源于前段时间,我们想做一个个人blog 后端用.NE ...
- Zookeeper_阅读源码第一步_在 IDE 里启动 zkServer(集群版)
上篇文章Zookeeper_阅读源码第一步_在 IDE 里启动 zkServer(单机版)讲了在 idea 里以单机的方式启动zookeeper,这篇介绍一下以集群的方式启动. 集群方式启动,才会真正 ...
- Java 源码学习线路————_先JDK工具包集合_再core包,也就是String、StringBuffer等_Java IO类库
http://www.iteye.com/topic/1113732 原则网址 Java源码初接触 如果你进行过一年左右的开发,喜欢用eclipse的debug功能.好了,你现在就有阅读源码的技术基础 ...
- Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析
Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...
- 如何读懂Framework源码?如何从应用深入到Framework?
如何读懂Framework源码? 首先,我也是一个应用层开发者,我想大部分有"如何读懂Framework源码?"这个疑问的,应该大都是应用层开发. 那对于我们来讲,读源码最大的问题 ...
- 读源码【读mybatis的源码的思路】
✿ 需要掌握的编译器知识 ★ 编译器为eclipse为例子 调试准备工作(步骤:Window -> Show View ->...): □ 打开调试断点Breakpoint: □ 打开变量 ...
- Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例
概要 前一章,我们学习了HashMap.这一章,我们对Hashtable进行学习.我们先对Hashtable有个整体认识,然后再学习它的源码,最后再通过实例来学会使用Hashtable.第1部分 Ha ...
随机推荐
- bzoj2754:[SCOI2012]喵星球上的点名(后缀自动机)
Description a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串 ...
- iis7下站点日志默认位置
在iis6时,通过iis管理器的日志配置可以找到站点日志存储的位置. 但是在iis7下,iis管理器下的日志配置只能找到iis日志配置的主目录,但到底在哪个子目录,则无法直接获知. 后来在主日 ...
- Run Faster-JAVA
又好久没有写点啥了,平时都忙于工作,忙于应付工作中的问题,各种吸收却并没有好好的消化,该是"反刍"一下的时候了. 本篇名叫"Run Faster,JAVA",其 ...
- react的一些思考
在做好第一个需求之后,我接到了一个react写的产品,这让我异常的兴奋,终于能写react了 开始做的时候整体框架已经搭建好了,这让我有点小失落,我还以为我要开始搭框架了呢,没事,搭的也挺好的. 有了 ...
- leetcode-575-Distribute Candies(计算一个数组中元素的种类的快速方法)
题目描述: Given an integer array with even length, where different numbers in this array represent diffe ...
- 1. java 的访问修饰符
一.什么情况下使用修饰符 属性通常使用private封装起来 方法一般使用public用于被调用 会被子类继承的方法,通常使用protected private protected package p ...
- 针对ACM输出格式的一个小技巧(对格式错误说不!)
printf("%d%c",bmax," \n"[i==n]); 上文中bmax为题目中需要输出的整形变量,可以脑补很多ans,max之类的,重点在于%c和后面 ...
- 解决kvm虚拟机启动之后,网卡eth0变为eth1问题
2018-12-19 故障前提 kvm虚拟机迁移到其他服务器上之后,重新启动网卡会出现问题 例如原网卡名称为eth0,迁移重启之后会自动变为eth1 为什么eth0会变成eth1? 很多Linux d ...
- 使用 json_serializable (flutter packages pub run build_runner build) 问题
命令: flutter packages pub run build_runner build 使用 build_runner 生成 .g.dart 文件 flutter packages pub r ...
- pandas数据清洗
1.我已安装好Anavonda3.5.所以我只用打开"jupyter notebook",然后打开浏览器 然后点击右侧的“new",然后打开python3