EF CORE中复杂类型的映射

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

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

 

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

@@@code

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

 

    }

@@#

 

自定义序列化

 

@@@code

 

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;

            }

 

        }

        }

 

    }

 

 

@@#

 

posted @ 2020-02-26 16:16  秦秋随  阅读(1018)  评论(0编辑  收藏  举报