Entity Framework Core 2.1 Preview1 新增功能简介 (2)

定义的UserInfo实体,用于保存用户信息,属性PhoneNumber表示用户的手机号码;为了用户信息安全,需要将手机号码进行加密后再保存到数据库,只是为了达到演示的目的,我们采用Base64进行编码。

public class UserInfo { public int Id { get; set; } public string PhoneNumber { get; set; } }

Base64ValueConverter表示进行值转换的具体逻辑,继承自泛型ValueConverter<string, string>,具体的逻辑非常简单,不再叙述。

public class Base64ValueConverter : ValueConverter<string, string> { public Base64ValueConverter() : base((v) => ToBase64(v), (v) => FromBase64(v)) { } private static string ToBase64(string input) { if (string.IsNullOrEmpty(input)) return input; var bytes = Encoding.UTF8.GetBytes(input); return Convert.ToBase64String(bytes); } private static string FromBase64(string input) { if (string.IsNullOrEmpty(input)) return input; var bytes = Convert.FromBase64String(input); return Encoding.UTF8.GetString(bytes); } }

SampleDbContext表示数据上下文,在OnModelCreating方法中,定义UserInfo实体的PhoneNumber属性需要使用Base64进行值转换。

public class SampleDbContext : DbContext { public DbSet<UserInfo> Users { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { var sqlConnectionStringBuilder = new SqlConnectionStringBuilder { DataSource = "*******", InitialCatalog = "ValueConverterTest", UserID = "sa", Password = "sa" }; optionsBuilder.UseSqlServer(sqlConnectionStringBuilder.ConnectionString); base.OnConfiguring(optionsBuilder); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<UserInfo>().Property(e => e.PhoneNumber).HasConversion(new Base64ValueConverter()); } }

下面的代码是对预期的结果进行单测。

[Fact] public async void ValueConverter_Test() { string phoneNumber = "13658556925"; using (SampleDbContext dbContext = new SampleDbContext()) { await dbContext.Database.EnsureDeletedAsync(); await dbContext.Database.EnsureCreatedAsync(); dbContext.Users.Add(new UserInfo() { PhoneNumber = phoneNumber }); await dbContext.SaveChangesAsync(); } UserInfo user; using (SampleDbContext dbContext = new SampleDbContext()) { user = dbContext.Users.Single(); } Assert.NotNull(user); Assert.Equal(phoneNumber, user.PhoneNumber); }

运行后,查询数据库中保存的结果:

Entity Framework Core 2.1 Preview1 新增功能简介

手机号码 13658556925 在数据库保存的值是 MTM2NTg1NTY5MjU=。

使用值转换的另一个常用场景是将枚举的值存储为字符串类型,默认情况下,枚举的值保存到数据库中是通过整数表示的,如果需要在值存储为字符串类型。

public enum CategoryName { Clothing, Footwear, Accessories } public class Category { public int Id { get; set; } public CategoryName Name { get; set; } }

实体Category的Name属性是用枚举表示的,如果在存储时用字符串类型表示,我们可以在DbContext的OnModelCreating方法中使用如下代码,

protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Category>().Property(e => e.Name).HasConversion<string>(); }

EF Core 默认提供常用类型的转换,我们只需指定存储的类型即可,框架默认支持的类型转换映射表如下:

源类型 目标类型
enum   int、short、long、sbyte、uint、ushort、ulong、byte、decimal、double、float  
bool   int、short、long、sbyte、uint、ushort、ulong、byte、decimal、double、float  
bool   string  
bool   byte[]  
char   string  
char   int、short、long、sbyte、uint、ushort、ulong、byte、decimal、double、float  
char   byte[]  
Guid   byte[]  
Guid   string  
byte[]   string  
string   byte[]  
DateTime、DateTimeOffset、TimeSpan   string、long、byte[]  
int、short、long、sbyte、uint、ushort、ulong、byte、decimal、double、float   string、byte[]  
LINQ GroupBy 解析

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzfwp.html