最近几天身体有点抱恙,说话都须要勇气,痛哭。今天简短的写一点探索性的内容,仅供了解,感谢您的阅读。数据库
在EF 6.x系列中写过一篇文章能够映射私有属性,说明EF的灵活性以及可扩展性,那么问题来了在EF Core是否一样能够呢,咱们来试试。ide
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<Blog> { public void Configure(EntityTypeBuilder<Blog> 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属性来访问,好比访问属性、主键、外键、导航属性皆可,接下来咱们迁移看看。ui
经过迁移生成的SQL语句咱们就可得出结论:在EF Core中映射私有属性和EF 6.x一模一样,只不过使用方式略有不一样罢了。spa
固然实际场景中,若属性为私有,那就没有映射到数据库中的必要了,这里只是做为探讨。下面咱们再来看看实际场景,好比上述中的Name属性为计算属性,那么此时咱们会进行以下映射:3d
public class BlogConfiguration : IEntityTypeConfiguration<Blog> { public void Configure(EntityTypeBuilder<Blog> 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()"); } }
此时咱们在控制台进行以下提交:code
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访问器设置为私有的呢,保持其只读而不可设置呢,改造以下便可:blog
public string Name { get; private set; }
如上设置Name为私有即不能手动为其赋值,那么咱们能够视为计算属性或者传参赋值,以下:get
private Blog() { } public Blog(string name) { Name = name; }
在EF Core中利用构造函数传参,那么必须显式存在无参构造函数,不然抛出异常,你懂的。再进一步讲,咱们也可将Name属性做为只做为字段来访问,配置成以下便可。string
public void Configure(EntityTypeBuilder<Blog> 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访问器都设置为公共的,虽然简便但可读性并那么强,是计算属性、仍是字段等等,都应显式设置,这样可读性会更好。