EF core 映射的数据转换——记RowVersion的读取

1,377 阅读3分钟

这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战

  • 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!
  • 📢本文作者:由webmote 原创,首发于 【掘金】
  • 📢作者格言: 生活在于折腾,当你不折腾生活时,生活就开始折腾你,让我们一起加油!💪💪💪

1.来自RowVersion的映射困惑

Sqlserve里的RowVersion类型的字段通常被用作乐观锁并发写,而我们平常使用的时候基本把它映射为byte[]即可,无需为它赋值。

但有时候由于业务需要,可能需要读取它,做些业务动作,我们该怎么映射它呢,能直接映射为long或ulong吗?

答案很客观,直接映射为其他类型,直接提示不能把byte[]映射为其他类型。

Stackoverflow有个伙计说,自己读到byte[],然后解析为ulong,哦哦哦,非常麻烦的了。

2. EF 值转换

其实EF提供了值转换功能,可以完成各种类型的读、写转换。

转换器允许在读取或写入数据库时转换属性值。 此转换可以从一个值转换为同一类型的另一个值,并且你不需要处理null这种情况,因为null数据不会调用该转换器。

3. 配置转换器

值转换在 DbContext.OnModelCreating中进行配置。

protected override void OnModelCreating(ModelBuilder modelBuilder) {
        modelBuilder 
        .Entity<Rider>()
        .Property(e => e.Mount)
        .HasConversion( 
        v => v.ToString(),
        v => (EquineBeast)Enum.Parse(typeof(EquineBeast), v)
        ); 
}

HasConversion 提供2个Func来完成clr类型到db 类型的转换,以及db类型到clr类型的转换。

EF内置了非常多的常用转换,以至于你几乎不用在重写这些转换。

例如:

modelBuilder .Entity<Rider>() .Property(e => e.Mount) .HasConversion<string>();

当然更简单的是直接使用属性标签Column

public class Rider2 { 
    public int Id { get; set; } 
    [Column(TypeName = "nvarchar(24)")]
    public EquineBeast Mount { get; set; }
}

modelBuilder .Entity<Rider2>() 
.Property(e => e.Mount) 
.HasColumnType("nvarchar(24)");

内置的转换有很多:

  • .HasConversion()
  • .HasConversion()
  • .HasConversion() ...

4. RowVersion的转换

SQL Server使用 8[字节二进制列][支持乐观 rowversion / timestamp 并发], 它们始终使用 8 字节数组从数据库中读取和写入。

但是,字节数组是可变的引用类型,这使得它们有点难以处理。

值转换器允许将其映射为 long等类型。

例如,假设 Blog 实体具有 ulong 并发令牌:

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ulong Version { get; set; }
}

可以使用值转换器将SQL rowversion 服务器列:

modelBuilder.Entity<Blog>()
    .Property(e => e.Version)
    .IsRowVersion()
    .HasConversion<byte[]>();

5.加密属性值

值转换器也可用于在将属性值发送到数据库之前对其进行加密,然后在读取时解密它们。

例如,使用字符串反转替代实际加密算法:

modelBuilder.Entity<User>().Property(e => e.Password).HasConversion(
    v => new string(v.Reverse().ToArray()),
    v => new string(v.Reverse().ToArray()));

6. 小结

有了值转换后,在操作数据库内的特殊类型时,方便了很多,这里不单单方便了RowVersion类型,注入json格式字符串、日期等特殊类型,均可以从值转换中受益。

例行小结,理性看待!

结的是啥啊,结的是我想你点赞而不可得的寂寞。😳😳😳

👓都看到这了,还在乎点个赞吗?

👓都点赞了,还在乎一个收藏吗?

👓都收藏了,还在乎一个评论吗?