如何使用Entity Framework Code-First将数组的双精度数据存储到数据库,而不影响现有代码和架构设计?
我查看了Data Annotation和Fluent API,我还考虑将double数组转换为字节字符串,并将该字节存储到自己的列中的数据库中。
我无法使用Fluent API访问public double[] Data { get; set; }
属性,我得到的错误消息是:
类型
double[]
必须是不可为空的值类型才能使用 它作为参数'T'。
存储Data
的类成功存储在数据库中,以及与此类的关系。我只缺少Data
列。
答案 0 :(得分:42)
你可以这样做:
[NotMapped]
public double[] Data
{
get
{
string[] tab = this.InternalData.Split(',');
return new double[] { double.Parse(tab[0]), double.Parse(tab[1]) };
}
set
{
this.InternalData = string.Format("{0},{1}", value[0], value[1]);
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public string InternalData { get; set; }
答案 1 :(得分:24)
感谢大家的投入,由于您的帮助,我能够找到解决此问题的最佳方法。这是:
public string InternalData { get; set; }
public double[] Data
{
get
{
return Array.ConvertAll(InternalData.Split(';'), Double.Parse);
}
set
{
_data = value;
InternalData = String.Join(";", _data.Select(p => p.ToString()).ToArray());
}
}
感谢这些stackoverflow帖子: String to Doubles array和 Array of Doubles to a String
答案 2 :(得分:5)
我知道它有点贵,但你可以这样做
class Primitive
{
public int PrimitiveId { get; set; }
public double Data { get; set; }
[Required]
public Reference ReferenceClass { get; set; }
}
// This is the class that requires an array of doubles
class Reference
{
// Other EF stuff
// EF-acceptable reference to an 'array' of doubles
public virtual List<Primitive> Data { get; set; }
}
现在,这将把单个实体(此处为'Reference')映射到Primitive类的'list'。这基本上是为了让SQL数据库感到高兴,并允许您适当地使用您的数据列表。
这可能不适合您的需求,但会让EF感到高兴。
答案 3 :(得分:4)
如果您使用List<double>
而不是double[]
,那将会容易得多。您已经有一个存储Data
值的表格。您可能从某个表到存储双值的表中有外键。创建另一个反映存储双精度表的模型,并在映射类中添加外键映射。这样,您就不需要添加一些复杂的后台逻辑来检索或存储类属性中的值。
答案 4 :(得分:1)
这是对Joffrey Kern的答案的一个小改进,允许任何长度的列表(未经测试):
[NotMapped]
public IEnumerable<double> Data
{
get
{
var tab = InternalData.Split(',');
return tab.Select(double.Parse).AsEnumerable();
}
set { InternalData = string.Join(",", value); }
}
[EditorBrowsable(EditorBrowsableState.Never)]
public string InternalData { get; set; }
答案 5 :(得分:1)
不要使用双[]使用List insted。
喜欢这个。
public class MyModel{
...
public List<MyClass> Data { get; set; }
...
}
public class MyClass{
public int Id { get; set; }
public double Value { get; set; }
}
我看到的所有解决方案都很糟糕,因为:
如果您创建表格,则不希望存储如下数据:&#34; 99.5,89.65,78.5,15.5&#34;那是无效的!首先它是一个字符串,意味着你可以在其中输入字母,当你的ASP.NET服务器调用double.Parse它将导致FormatException并且你真的不想要!
速度较慢,因为您的服务器必须解析字符串。为什么要解析字符串而不是从SQL Server中获取几乎准备好的数据?
答案 6 :(得分:1)
如果您的集合可以是 null
,并且您希望保留它,请执行以下操作:
[NotMapped]
public double[] Data
{
get => InternalData != null ? Array.ConvertAll(Data.Split(';'), double.Parse) : null;
set => InternalData = value != null ? string.Join(";", value) : null;
}
此外,在字符串属性上指定 [Column(TypeName = "varchar")]
以获得更高效的存储数据类型。
答案 7 :(得分:0)
对 @Jonas's 答案的完美改进是添加必要的注释。所以,一个更干净的版本是
[EditorBrowsable(EditorBrowsableState.Never)]
[JsonIgnore]
public string InternalData { get; set; }
[NotMapped]
public double[] Data
{
get => Array.ConvertAll(InternalData.Split(';'), double.Parse);
set
{
InternalData = string.Join(";", value.Select(p => p.ToString(CultureInfo.InvariantCulture)).ToArray());
}
}
[JsonIgnore] 注释将忽略来自 JSON 序列化和 Swagger UI 的 InternalData 字段。
[EditorBrowsable(EditorBrowsableState.Never)] 将从 IDE 智能感知中隐藏公共方法