gpt4 book ai didi

C# - 在 .Net Core 3.1 中使用 Entity Framework Core 3 HasConversion 将字段转换为 JSON

转载 作者:行者123 更新时间:2023-12-04 08:15:06 26 4
gpt4 key购买 nike

我试图在我的项目中的所有模型中动态完成转换:

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;
}
}
为简单起见,我使用此 User 模型:
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对象作为另一个 model没有 Key并抛出一个错误告诉我添加一个 Key/PK即使这没有标记为模型。
现在,如果我从 User -> Configure() 执行此操作它会起作用,但它会向我展示其他问题,例如模型失去了自己的关系以及与其他模型的关联,现在它向我抛出了其他一系列我什至没有的错误。
我也注意到 EF删除 LocalizedName从属性列表中并将其显示在 Navigation 下属性列表。最后,我检查了 OnModelCreating -> modelBuilder.Model.GetEntityTypes()并注意到 EF 将其视为新的 Model这有点奇怪。
有什么办法可以告诉我 EF将此标记为 string/json字段而不是 EF 自动假设它是一个模型?
任何帮助,将不胜感激。

最佳答案

您可以在 OnModelCreating 中忽略您的实体像这样:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Ignore<LocalizedName>();
//rest of your code
}
并忽略所有具有 HasJsonConversion 的模型您可以执行此操作的属性(我没有测试过):
       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();

modelBuilder.Ignore(property.PropertyType);
}
}

关于C# - 在 .Net Core 3.1 中使用 Entity Framework Core 3 HasConversion 将字段转换为 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65745810/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com