最近幾天身體有點抱恙,說話都須要勇氣,痛哭。今天簡短的寫一點探索性的內容,僅供瞭解,感謝您的閱讀。數據庫
在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訪問器都設置爲公共的,雖然簡便但可讀性並那麼強,是計算屬性、仍是字段等等,都應顯式設置,這樣可讀性會更好。