EntityFramework Core是否可以映射私有屬性呢?了解一下。


前言

最近幾天身體有點抱恙,說話都需要勇氣,痛哭。今天簡短的寫一點探索性的內容,僅供了解,感謝您的閱讀。

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<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屬性來訪問,比如訪問屬性、主鍵、外鍵、導航屬性皆可,接下來我們遷移看看。

通過遷移生成的SQL語句我們就可得出結論:在EF Core中映射私有屬性和EF 6.x如出一轍,只不過使用方式略有不同罷了。

當然實際場景中,若屬性為私有,那就沒有映射到數據庫中的必要了,這里只是作為探討。下面我們再來看看實際場景,比如上述中的Name屬性為計算屬性,那么此時我們會進行如下映射:

    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()");
        }
    }

此時我們在控制台進行如下提交:

            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<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訪問器都設置為公共的,雖然簡便但可讀性並那么強,是計算屬性、還是字段等等,都應顯式設置,這樣可讀性會更好。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM