博客
关于我
EntityFramework Core是否可以映射私有属性呢?了解一下。
阅读量:406 次
发布时间:2019-03-05

本文共 3297 字,大约阅读时间需要 10 分钟。

前言

最近几天身体有点抱恙,说话都需要勇气,痛哭。今天简短的写一点探索性的内容,仅供了解,感谢您的阅读。

EF Core映射私有属性

在EF 6.x系列中写过一篇文章可以映射私有属性,说明EF的灵活性以及可扩展性,那么问题来了在EF Core是否同样可以呢,我们来试试。

public class Blog    {        public int Id { get; set; }        private string Name { get; set; }        public string Url { get; set; }        public DateTime CreatedTime { get; set; }        public DateTime ModifiedTime { get; set; }        public byte Status { get; set; }        public bool IsDeleted { get; set; }    }

如上代码,我们将Name设置私有属性,接下来我们利用EF Core提供给我们的APi来访问是否可以进行映射到数据库表中呢?我们来尝试一下。

public class BlogConfiguration : IEntityTypeConfiguration
{ public void Configure(EntityTypeBuilder
builder) { var nonPublicProperties = builder.Metadata.ClrType.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance); foreach (var p in nonPublicProperties) { builder.Property(p.Name).HasColumnType("VARCHAR(50)"); } builder.Property(p => p.CreatedTime).HasColumnType("DATETIME").HasDefaultValueSql("GETDATE()"); } }
protected override void OnModelCreating(ModelBuilder modelBuilder)        {            modelBuilder.ApplyConfiguration(new BlogConfiguration());            base.OnModelCreating(modelBuilder);        }

在EF Core中如若我们需要访问元数据,则需要借助于在映射配置中即如上builder中的Metadata属性来访问,比如访问属性、主键、外键、导航属性皆可,接下来我们迁移看看。

通过迁移生成的SQL语句我们就可得出结论:在EF Core中映射私有属性和EF 6.x如出一辙,只不过使用方式略有不同罢了。

当然实际场景中,若属性为私有,那就没有映射到数据库中的必要了,这里只是作为探讨。下面我们再来看看实际场景,比如上述中的Name属性为计算属性,那么此时我们会进行如下映射:

public class BlogConfiguration : IEntityTypeConfiguration
{ public void Configure(EntityTypeBuilder
builder) { builder.Property(p => p.Name).IsRequired().HasComputedColumnSql("((N'cnblogs'+CONVERT([CHAR](8),[CreatedTime],(112)))+RIGHT(REPLICATE(N'0',(6))+CONVERT([NVARCHAR],[Id],(0)),(6)))"); builder.Property(p => p.CreatedTime).HasColumnType("DATETIME").HasDefaultValueSql("GETDATE()"); } }

此时我们在控制台进行如下提交:

var context = new EFCoreDbContext();            context.Add(new Blog()            {                IsDeleted = false,                Status = 0,                ModifiedTime = DateTime.Now,                Url = "http://www.cnblogs.com/createmyself",                Name = "2222"            });            var result = context.SaveChanges();

因为我们将上述Name配置为计算属性,但是此时Name属性中的SET访问器是公共的,所以可能会有误操作对其进行赋值,当然即使手动赋值,最终依然能正确提交,结果不受任何影响,只能说这样可读性不太好,既然Name为计算属性即数据库自动为其赋了值,那么我们为何不将SET访问器设置为私有的呢,保持其只读而不可设置呢,改造如下即可:

public string Name { get; private set; }

 如上设置Name为私有即不能手动为其赋值,那么我们可以视为计算属性或者传参赋值,如下:

private Blog() { }        public Blog(string name)        {            Name = name;        }

在EF Core中利用构造函数传参,那么必须显式存在无参构造函数,否则抛出异常,你懂的。再进一步讲,我们也可将Name属性作为只作为字段来访问,配置成如下即可。

public void Configure(EntityTypeBuilder
builder) { var property = builder.Metadata.FindProperty(nameof(Blog.Name)); property.SetPropertyAccessMode(PropertyAccessMode.Field); builder.Property(p => p.Name).HasColumnType("VARCHAR(50)"); builder.Property(p => p.CreatedTime).HasColumnType("DATETIME").HasDefaultValueSql("GETDATE()"); }

总结

本节稍微探讨了下EF Core中如何映射私有属性,虽然没有什么实际作用,可作为了解。想必很多时候,我们都会将属性GET或者SET访问器都设置为公共的,虽然简便但可读性并那么强,是计算属性、还是字段等等,都应显式设置,这样可读性会更好。

你可能感兴趣的文章
MySQL中ON DUPLICATE KEY UPDATE的介绍与使用、批量更新、存在即更新不存在则插入
查看>>
MYSQL中TINYINT的取值范围
查看>>
MySQL中UPDATE语句的神奇技巧,让你操作数据库如虎添翼!
查看>>
Mysql中varchar类型数字排序不对踩坑记录
查看>>
MySQL中一条SQL语句到底是如何执行的呢?
查看>>
MySQL中你必须知道的10件事,1.5万字!
查看>>
MySQL中使用IN()查询到底走不走索引?
查看>>
Mysql中使用存储过程插入decimal和时间数据递增的模拟数据
查看>>
MySql中关于geometry类型的数据_空的时候如何插入处理_需用null_空字符串插入会报错_Cannot get geometry object from dat---MySql工作笔记003
查看>>
mysql中出现Incorrect DECIMAL value: '0' for column '' at row -1错误解决方案
查看>>
mysql中出现Unit mysql.service could not be found 的解决方法
查看>>
mysql中出现update-alternatives: 错误: 候选项路径 /etc/mysql/mysql.cnf 不存在 dpkg: 处理软件包 mysql-server-8.0的解决方法(全)
查看>>
Mysql中各类锁的机制图文详细解析(全)
查看>>
MySQL中地理位置数据扩展geometry的使用心得
查看>>
Mysql中存储引擎简介、修改、查询、选择
查看>>
Mysql中存储过程、存储函数、自定义函数、变量、流程控制语句、光标/游标、定义条件和处理程序的使用示例
查看>>
mysql中实现rownum,对结果进行排序
查看>>
mysql中对于数据库的基本操作
查看>>
Mysql中常用函数的使用示例
查看>>
MySql中怎样使用case-when实现判断查询结果返回
查看>>