在项目中用到EntityFramework Core都是现学现用,及时发现问题及时测试,私下利用休闲时间也会去学习其他未曾遇到过或者用过的特性,本节我们来讲讲在EntityFramework Core 1.1中出现了哪些新特性供我们使用。
EntityFramework Core 1.1新特性探讨 DbSet.Find在EF 6.x中也有此方法的实现,在EF Core 1.1中也同样对此方法进行了实现,为什么要拿出来讲呢,当然也有其道理,我们一起来看看。在仓储中我们实现Find这个方法,如下:
public virtual T Find(int Key) { return _context.Set<T>().Find(Key); }
此时我们来查询Blog中主键等于1的数据。
var blog1 = _blogRepository.Find(1);
此时我们通过SQL Server Profiler监控得到如下SQL。
我们看到通过Find方法来查询主键等于1的数据时,声明了一个变量然后再来进行设置变量值进行查询,没毛病,上述我们是直接通过Find方法来实现,下面我们通过其他几种方法来实现。如下:
public T GetSingle(int id) { return _context.Set<T>().FirstOrDefault(x => x.Id == id); }
var blog = _blogRepository.GetSingle(1);
此时和上述Find方法执行的SQL无任何区别,我们先别着急下结论,我们再来通过lambda表达式来实现看看。
public T GetSingle(Expression<Func<T, bool>> predicate) { return _context.Set<T>().FirstOrDefault(predicate); }
var blog = _blogRepository.GetSingle(d => d.Id == 1);
此时我们再来看看生成的SQL语句。
此时生成的SQL语句没有声明变量看起来非常清爽,同时看过dudu老大刚不久写过在EF Core中我们声明的的lambda表达式中的参数就是我们查询表的别名,确实是如此,不知道你发现了没有。既然以上有多种实现且利用lambda表达式实现更加清爽,那么为何还要搞出一个Find方法呢,请继续往下看。
var blog = _blogRepository.GetSingle(d => d.Id == 1); var blog1 = _blogRepository.Find(1);
当我们第一次查询了主键等于1的数据时,我们第二次通过Find方法再来进行查询时通过监控SQL Server Profiler,你会发现并未生成任何SQL语句,这说明什么呢,说明EF Core团队给出Find方法的目的在于:当实体已经被加载到上下文中时,我们通过Find方法再去查询数据时此时不会再去数据库中进行查询。所以当我们利用主键查询数据时利用Find方法会减少对数据库的多次请求。
ICollection<T>(集合类型映射支持)在之前EF版本中我们都是进行如下声明字段
public class Blog : IEntityBase { Id { get; set; } Name { get; set; } Url { get; set; } public virtual ICollection<Post> Posts { get; set; } }
我们知道在EF Core中已经不存在延迟加载这一概念,所以请用了EF Core的童鞋将virtual关键字去掉。同时我们在映射集合时一直以来都统一用的ICollection<T>,但是在EF Core中不再有此局限性,我们进行如下定义:
public class Blog : IEntityBase { public int Id { get; set; } public string Name { get; set; } public string Url { get; set; } public IEnumerable<Post> Posts { get; set; } }
通过如上我们知道现在支持了IEnumerable<T>集合的映射。当然这里有个前提,其具体集合类必须实现ICollection接口,否则EntityFramework Core将无法进行填充。
Mapping to Fileds(映射到字段)这个特性应该是前所未有,只有在EF Core 1.1中才出现,我们详细讲解下Backing Fileds(我们暂且将其翻译为返回字段)特性。自从有了如下自动属性的出现,就方便了我们许多。
public string Url { get; set; }
什么是返回字段(Backing Fileds)特性,我们先看下原始为字段配置属性的情况如下:
private string _url; public string Url { get { return _url; } set { _url = value; } }
Backing Fileds特性允许EF Core读或者写数据到字段中而不是属性中。也就是说如上EF Core将数据读写到_url字段中而不是Url中。默认情况下满足以下四种规则都会配置成Backing Fileds。