将任何对象存储为字符串,但将其公开为类型化对象或将任何类型的非字符串属性映射到字符串列

本文关键字:字符串 任何 对象 属性 类型 映射 存储 类型化 | 更新日期: 2023-09-27 18:11:24

我需要使用EntityFramework在数据库中存储不同的参数。该值需要以字符串类型存储,但有额外的列来指定它是字符串,int, double等。

但是,当我从数据库中检索值时,我需要将其映射到有效类型。简化的类看起来像这样:

public class Parameter
{
    public long Id {get; set;}
    public string Type {get; set;}
}
public class ParameterValues
{
    public long Id {get; set;}
    public virtual Parameter {get;set;}
    public string Value {get;set;}
}
public class Document
{
    public long Id {get; set;}
    public virtual ICollection<ParameterValues> ParameterValues {get;set;}
}

所以,我想我需要写一个方法,将转换检索值从数据库,但我不知道如何做到这一点。

我试着写一些额外的类,比如:

public class IntValue : ParameterValue
{
    public new int Value {get;set;}
}

那么我的方法将遍历collection:

private void Convert()
{
    foreach (ParameterValue param in ParameterValues)
    {
        if (param.Parameter.Type == "Int")
        {
            IntParameter intParameter = param;
        }
    }
}

但是它当然不是这样工作的。有人知道如何映射字符串值ParameterValue类与正确的值类型?

将任何对象存储为字符串,但将其公开为类型化对象或将任何类型的非字符串属性映射到字符串列

当我需要做这样的事情时,我使用[NotMapped]属性,它允许我像这样检索和存储值:

[NotMapped]
public object TypedValue
{
    get 
    { 
       switch(Type)
       {
          case "int":
             return int.Parse(Value); // parse to whatever needed, with a switch
          // ...
       }
    }
    set
    {
      switch(value.GetType)
      {
          case typeof(int):
             Value = // format to allow later parsing
             break;
          // ...
      }
    }
}

包含一些细节(例如,null处理)。

然而,最合理的方法是使用序列化器(JSON、二进制、XML或其他)来序列化和反序列化值,这样就可以避免所有的切换(如果你做得对,序列化的值具有类型信息,可以直接反序列化为正确的类型)。我将公开[NotMapped] object Value属性并包含映射到db列的SerializedValue,而不是格式化和解析,我将使用"序列化/反序列化",以类似于示例代码的方式。

不如这样写:

public class Parameter
{
    public long Id {get; set;}
    public string Type {get; set;}
}
public class ParameterValues
{
    public long Id {get; set;}
    public Parameter Parameter {get; set;}
    public string Value {get;set;}
    public ParameterValues(long id, Parameter param, string val)
    {
        Id = id;
        Parameter = param;
        Value = val;
    }
}
public class IntValue : ParameterValues
{
    public IntValue(ParameterValues value)
        : base(value.Id, value.Parameter, value.Value)
    {
    }
    public int GetValue()
    {
        return Int32.Parse(Value);
    }
}

然后Convert可以是这样的:

public List<ParameterValues> Convert(List<ParameterValues> values)
{
    var newValues = new List<ParameterValues>();
    foreach (var val in values)
    {
        if (val.Parameter.Type == "Int")
        {
            newValues.Add(new IntValue(val));
        }
    }
    return newValues;
}