我们在数据库设计的时候,有一些字段需要输入JSON/数组格式的话在EfCode里就需要转换。当然我们也可以不转换值,那么JSON格式的数据就需要转换为字符串存入数据库中,然后从数据库里取出来在转换为JSON,这样就增加了很多的工作量。那么在这种前提下,我们就需要对数据进行自动的转换。
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Coupon>(b => { b.Property(b => b.ExpireTime).HasConversion(v => My.Stringify(v) ?? "[]", v => My.GetJson<string>(v)); }); }
上诉代码就是转换一个时间的数据,让数据库取出的字符串自动变为LIST数组。这样我们就不需要特意的转换了。
但如果仅仅是上面的代码,虽然使用没有问题,但是我们在数据库迁移中没有做值比较的话就会导致迁移失败,那么如果正常使用的话代码就要改写一下了。如下
b.Property(b => b.ExpireTime).HasConversion(v => My.Stringify(v) ?? "[]" , v => My.GetJson<string>(v), new ValueComparer<IEnumerable<string>>( (c1, c2) => c1!.SequenceEqual(c2!), c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), // c tolist 的话就是复制一份 c => c.ToList() ) ); });
上诉代码看起来是不是很杂乱不堪,如果需要转换的字段比较多可读性和美观都非常差?那么我们就需要进行一下优雅的封装看了。首先建立一个拓展类文件EntityTypeBuilderExtensions.cs
public static class EntityTypeBuilderExtensions { /// <summary> /// 比较泛型的数据如[{txt:1}] /// </summary> /// <typeparam name="T"></typeparam> /// <param name="propertyBuilder"></param> /// <returns></returns> public static PropertyBuilder<IEnumerable<T>> HasJsonConversionList<T>( this PropertyBuilder<IEnumerable<T>> propertyBuilder) { return propertyBuilder .HasConversion( v => My.Stringify(v) ?? "[]", v => My.GetJson<T>(v), new ValueComparer<IEnumerable<T>>( (c1, c2) => c1!.SequenceEqual(c2!), c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v!.GetHashCode())), // c tolist 的话就是复制一份 c => c.ToList() ) ); } /// <summary> /// 比较对象如{txt:1} /// </summary> /// <typeparam name="T"></typeparam> /// <param name="propertyBuilder"></param> /// <returns></returns> public static PropertyBuilder<T> HasJsonConversion<T>( this PropertyBuilder<T> propertyBuilder) where T : class, new() { return propertyBuilder .HasConversion( v => My.Stringify(v) ?? "{}", v => My.Parse<T>(v) ?? new T(), new ValueComparer<T>( (l, r) => (l == null && r == null) || (l != null && l.Equals(r)), v => v == null ? 0 : v.GetHashCode(), v => v == null? new T(): My.Parse<T>(v) ?? new T() ) ); } }
这是我设计的类来比较2种类型的数据,当然您可以根据自己的需求进行设计。创建好后然后我们在OnModelCreating里的代码就可以非常简洁了。代码如下
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<HkUser>(b => { b.Property(b => b.IdCard).HasJsonConversionList<string>(); }); modelBuilder.Entity<Orders>().Property(o => o.Address).HasJsonConversion<Address>(); }
怎么样,看起来是不是简洁多了。通过上诉的操作我们就可以自由的往数据库里存入json类型的数据而在取出后又可以自动的转换成相应的数据类型。好了,如果您有C#类型的开发可以联系我们,微信和QQ号码都是:24722