EF CORE中复杂类型的映射
实体映射时,遇到复杂类型,可选择下述方法处理:
- NotMapped,跳过映射
- 在复杂类型上声明 [Owned],但仅限该复杂类型是全部由简单值类型组成的
- 自定义序列化方法
示例: IPInfo使用了owned,对IPEndPoint使用自定义序列化,对VersionInfo使用JSON序列化
public class Controller : IController
{
public int SN { get; set; }
public IPInfo IPInfo { get; set; } = IPInfo.Default;
[Column(TypeName = "string")]
public VersionInfo VersionInfo { get; set; } = VersionInfo.Default;
[Column(TypeName = "string")]
public System.Net.IPEndPoint ServerIPEndPoint { get; set; } = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
public DateTime Time { get; set; } = DateTime.Now;
}
[Owned]
public class IPInfo
{
public static IPInfo Default { get; } = new IPInfo()
{
IP="192.168.0.254"
};
public string IP { get; set; }
public ushort Port { get; set; } = 60000;
public string Mac { get; set; }
public string Mask { get; set; } = "255.255.255.0";
public string Gateway { get; set; } = "192.168.0.1";
public bool Force { get; set; }
}
@@#
自定义序列化
public class IPEndPointConverter : ValueConverter<System.Net.IPEndPoint, string>
{
public IPEndPointConverter(ConverterMappingHints mappingHints = null)
: base(
v => v.ToString(),
v => System.Net.IPEndPoint.Parse(v),
mappingHints)
{
}
public static ValueConverterInfo DefaultInfo { get; }
= new ValueConverterInfo(typeof(System.Net.IPEndPoint), typeof(string), i => new IPEndPointConverter(i.MappingHints));
}
public class JsonConverter<T> : ValueConverter<T, string>
{
public JsonConverter() : this(null)
{
}
public JsonConverter(ConverterMappingHints mappingHints = null)
: base(
v => v.SerializeObject(),
v => v.Deserialize<T>(),
mappingHints)
{
}
public static ValueConverterInfo DefaultInfo { get; }
= new ValueConverterInfo(typeof(T), typeof(string), i => new JsonConverter<T>(i.MappingHints));
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
void aa<T>() where T : class
{
modelBuilder.Entity<T>().ToTable(typeof(T).Name.ToLower());
}
aa<User>();
aa<Device>();
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
foreach (var property in entityType.GetProperties())
{
if (property.ClrType.IsValueType && !property.ClrType.IsGenericType)
continue;
switch (property.ClrType.Name)
{
case nameof(System.Net.IPEndPoint):
property.SetValueConverter(new IPEndPointConverter()); //演示 owned效果,仅限复杂类型是由简单类型组成的,没有内嵌复杂类型
break;
case nameof(String):
break;
default:
Type genType = typeof(JsonConverter<>).MakeGenericType(property.ClrType);
ValueConverter obj = Activator.CreateInstance(genType) as ValueConverter;
property.SetValueConverter(obj);
break;
}
}
}
}
@@#