EF CORE中复杂类型的映射

实体映射时,遇到复杂类型,可选择下述方法处理:

  1. NotMapped,跳过映射
  2. 在复杂类型上声明 [Owned],但仅限该复杂类型是全部由简单值类型组成的
  3. 自定义序列化方法

示例: IPInfo使用了owned,对IPEndPoint使用自定义序列化,对VersionInfo使用JSON序列化

@@@code

publicclassController : IController

{

publicint 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]

publicclassIPInfo

{

publicstatic IPInfo Default { get; } = new IPInfo()

{

IP="192.168.0.254"

};

publicstring IP { get; set; }

publicushort Port { get; set; } = 60000;

publicstring Mac { get; set; }

publicstring Mask { get; set; } = "255.255.255.0";

publicstring Gateway { get; set; } = "192.168.0.1";

publicbool Force { get; set; }

}

@@#

自定义序列化

@@@code

publicclassIPEndPointConverter : ValueConverter<System.Net.IPEndPoint, string>

{

publicIPEndPointConverter(ConverterMappingHints mappingHints = null)

: base(

v => v.ToString(),

v => System.Net.IPEndPoint.Parse(v),

mappingHints)

{

}

publicstatic ValueConverterInfo DefaultInfo { get; }

= new ValueConverterInfo(typeof(System.Net.IPEndPoint), typeof(string), i => new IPEndPointConverter(i.MappingHints));

}

publicclassJsonConverter<T> : ValueConverter<T, string>

{

publicJsonConverter() : this(null)

{

}

publicJsonConverter(ConverterMappingHints mappingHints = null)

: base(

v => v.SerializeObject(),

v => v.Deserialize<T>(),

mappingHints)

{

}

publicstatic ValueConverterInfo DefaultInfo { get; }

= new ValueConverterInfo(typeof(T), typeof(string), i => new JsonConverter<T>(i.MappingHints));

}

protectedoverridevoid 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;

}

}

}

}

@@#

(0)

相关推荐