【发布时间】:2021-01-16 02:04:29
【问题描述】:
我试图在我项目中的所有模型中动态完成转换:
DbContext.cs
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var entityTypes = modelBuilder.Model.GetEntityTypes().ToList();
foreach (var entityType in entityTypes)
{
foreach (var property in entityType.ClrType.GetProperties().Where(x => x != null && x.GetCustomAttribute<HasJsonConversionAttribute>() != null))
{
modelBuilder.Entity(entityType.ClrType)
.Property(property.PropertyType, property.Name)
.HasJsonConversion();
}
}
base.OnModelCreating(modelBuilder);
}
然后创建了一个数据注释属性来将我的模型中的字段标记为“Json”
public class HasJsonConversionAttribute : Attribute {}
这是我用于将 Json 转换为对象并返回 Json 的扩展方法
public static class SqlExtensions
{
public static PropertyBuilder HasJsonConversion(this PropertyBuilder propertyBuilder)
{
ParameterExpression parameter1 = Expression.Parameter(propertyBuilder.Metadata.ClrType, "v");
MethodInfo methodInfo1 = typeof(Newtonsoft.Json.JsonConvert).GetMethod("SerializeObject", types: new Type[] { typeof(object) });
MethodCallExpression expression1 = Expression.Call(methodInfo1 ?? throw new Exception("Method not found"), parameter1);
ParameterExpression parameter2 = Expression.Parameter(typeof(string), "v");
MethodInfo methodInfo2 = typeof(Newtonsoft.Json.JsonConvert).GetMethod("DeserializeObject", 1, BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder, CallingConventions.Any, types: new Type[] { typeof(string) }, null)?.MakeGenericMethod(propertyBuilder.Metadata.ClrType) ?? throw new Exception("Method not found");
MethodCallExpression expression2 = Expression.Call(methodInfo2, parameter2);
var converter = Activator.CreateInstance(typeof(ValueConverter<,>)
.MakeGenericType(propertyBuilder.Metadata.ClrType, typeof(string)), new object[]
{
Expression.Lambda( expression1,parameter1),
Expression.Lambda( expression2,parameter2),
(ConverterMappingHints) null
});
propertyBuilder.HasConversion(converter as ValueConverter);
return propertyBuilder;
}
}
为简单起见,我使用的是这个用户模型:
public class User : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
// Apply some settings defined in custom annotations in the model properties
//builder.ApplyCustomAnnotationsAndConfigs(this);
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Username { get; set; }
[HasJsonConversion]
public List<LocalizedName> Values { get; set; }
}
这是我要与 JSON 相互转换的类:
public class LocalizedName
{
public string Value { get; set; }
public string Code { get; set; }
}
现在这是我面临的问题,它继续将LocalizedName 对象检测为另一个没有Key 的model,并抛出一个错误,告诉我添加Key/PK,即使这是未标记为模型。
现在,如果我从 User -> Configure() 执行此操作,它会起作用,但它会向我显示其他问题,例如模型失去与其他模型的关系和关联,现在它会抛出我没有的其他一组错误甚至一开始就有。
我还注意到EF 从属性列表中删除了LocalizedName 并将其显示在Navigation 属性列表下。最后,我检查了OnModelCreating -> modelBuilder.Model.GetEntityTypes(),发现 EF 将其视为新的Model,这有点奇怪。
有没有办法让 EF 将此标记为 string/json 字段,而不是 EF 自动假设它是一个模型?
任何帮助将不胜感激。
【问题讨论】:
-
你标记了这个 EF 而不是 EF 核心
-
@SoiidSnake 你看过这篇文章了吗? stackoverflow.com/questions/44829824/…
-
@GetFuzzy - 我做到了.. 他们没有提到任何关于这个问题的内容。
标签: c# json .net asp.net-core entity-framework-core