首页 > 解决方案 > 是否可以使用实体框架 6 将实体的多个属性读/写到单个列中?如何?

问题描述

给定以下模型(UserXyz),我希望 Entity Framework 将 User 的 Xyz 属性写入单个列,而不是创建并将它们写入三列(Xyz_XXyz_YXyz_Z)。

  1. 是否可以为实体框架自定义序列化器/序列化器来做到这一点?
  2. 如何?

谢谢!

楷模:

public class Xyz
{
    public int X { get; set; }
    public int Y { get; set; }
    public int Z { get; set; }

    public static implicit operator string(Xyz d) => $"{d.X};{d.Y};{d.Z}";

    public static implicit operator Xyz(string s)
    {
        var separators = new char[] { ';' };
        var t = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);
        return new Xyz
        {
            X = int.Parse(t[0]),
            Y = int.Parse(t[1]),
            Z = int.Parse(t[2]),
        };
    }
}

public class User
{
    public int ID { get; set; }
    public string Name { get; set; }
    public Xyz Xyz { get; set; }
}

上述模型的数据库表

用户表现在(当前):

ID 姓名 Xyz_X XYZ_Y XYZ_Z
1 爱丽丝 0 1 2
2 鲍勃 -1 999 777

具有自定义序列化/序列化的用户表(我想要的):

ID 姓名 XYZ
1 爱丽丝 0;1;2
2 鲍勃 -1;999;777

更新:使用解决方法

由于EF6不支持ValueConverter(请参阅评论!)并且我无法将整个项目更改/重写/迁移到Core 3.1,因此我使用了以下解决方法:

  1. User类添加了第二个属性DbXyz
  2. User类的Xyz属性添加了NotMapped属性

现在EF在读取/写入时忽略属性Xyz ,但属性DbXyz被滥用为属性 Xyz 的转换

重要的是注释和命名新的“转换器”属性DbXyz,以便其他开发人员了解不要在他们的算法中使用 get/set,而是使用Xyz属性。

public class Xyz
{
    public int X { get; set; }
    public int Y { get; set; }
    public int Z { get; set; }

    public override string ToString() => $"{X};{Y};{Z}";

    public static implicit operator string(Xyz d) => d.ToString();

    public static implicit operator Xyz(string s)
    {
        var separators = new char[] { ';' };
        var t = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);
        return new Xyz
        {
            X = int.Parse(t[0]),
            Y = int.Parse(t[1]),
            Z = int.Parse(t[2]),
        };
    }
}

public class User
{
    public int ID { get; set; }
    public string Name { get; set; }

    [NotMapped]
    public Xyz Xyz { get; set; }

    // Used only to read/write from database!
    public string DbXyz
    {
        get => Xyz.ToString();
        set => Xyz= value;
    }
}

标签: c#databaseentity-frameworkserializationcustomization

解决方案


推荐阅读