比如属性为UserName,那么对应的Backing Fileds则依次是:_userName,_UserName,m_userName,m_UserName。配置Backing Fileds后,当从数据库查询类实例后将直接将其对应数据写到字段中,在其他时候当EF Core需要读或者写值时有可能使用属性,例如EF需要更新一个属性上的值时,此时将使用属性的set访问器,如果属性仅仅只是只读,那么将值写到字段中。例如如下配置Backing Fileds即_validateUrl。
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .Property(b => b.Url) .HasField(); } } public class Blog { private string _validatedUrl; public int BlogId { get; set; } public string Url { get { return _validatedUrl; } } public void SetUrl(string url) { using (var client = new HttpClient()) { var response = client.GetAsync(url).Result; response.EnsureSuccessStatusCode(); } _validatedUrl = url; } }
我们也可以在映射中配置使用属性还是字段,如下:
modelBuilder.Entity<Blog>() .Property(b => b.Url) .HasField() .UsePropertyAccessMode(PropertyAccessMode.Field);
若我们在实体中没有属性,此时我们可以通过字段来存储数据。我们通过映射中的Porperty(...)来指定字段名称,若没有属性,此时EF Core将会查找字段,如下:
class MyContext : DbContext { public DbSet<Blog> Blogs { get; set; } OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .Property(); } } public class Blog { private string _validatedUrl; public int BlogId { get; set; } public string GetUrl() { return _validatedUrl; } public void SetUrl(string url) { using (var client = new HttpClient()) { var response = client.GetAsync(url).Result; response.EnsureSuccessStatusCode(); } _validatedUrl = url; } }
讲了这么多Backing Fileds特性,不知道看到本篇文章的你清楚了它的作用是什么,为什么要提出Backing Fileds特性,它存在的价值或者说用途是做什么呢,就我个人的理解的话,提出Backing Fileds的多数场景在:如果属性只读,我们需要通过其他逻辑操作来获取其值,但是我们没有一个桥梁来赋予其值,此时我们就需要Backing Fileds来完成。希望看到此文的你有更多见解的话,请留下评论,一起探讨。这里我们结合上述IEnumerable<T>来进一步讲解Backing Fileds。我们在Blog类中是如下定义。
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; } }
我们知道对于导航属性Posts更多的是通过Inlcude来查询出Posts,所以在这里我们完全不需要set访问器以便减少对Posts反编译为Set方法,我们完全可以改造如下:
public IEnumerable<Post> Posts { get; } = new List<Post>();
话又说回来了,如果我们万一需要对Post进行一些操作,那么在这种情况下该如何是好呢,此时我们通过暴露IEnumerable<Blog>导航属性,然后借助该导航属性的Backing Fileds来对Post进行操作,改造如下:
public class Blog : IEntityBase { private readonly List<Post> _posts = new List<Post>(); public int Id { get; set; } public string Name { get; set; } public string Url { get; set; } public IEnumerable<Post> Posts => _posts; public void AddPost(Post post) { // Do some buisness your logic _posts.Add(post); } }
我们实际来操作一下,查询Blog数据以及导航属性Post数据。