property framework foreign first enum dataannotations data code c# .net entity-framework ef-code-first fluent-interface

c# - foreign - Cómo almacenar la matriz doble[] en la base de datos con el enfoque Entity Framework Code-First



enum entity framework (6)

Gracias a todos por sus aportaciones, gracias a su ayuda, pude encontrar la mejor manera de resolver esto. Cual es:

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

Gracias a estas publicaciones de stackoverflow: String to Doubles array y Array of Doubles to a String

¿Cómo puedo almacenar una matriz de dobles en la base de datos utilizando Entity Framework Code-First sin ningún impacto en el diseño de código y arquitectura existente?

He analizado Data Annotation y Fluent API, también he considerado convertir la doble matriz en una cadena de bytes y almacenar ese byte en la base de datos en su propia columna.

No puedo acceder al public double[] Data { get; set; } public double[] Data { get; set; } public double[] Data { get; set; } propiedad con Fluent API, el mensaje de error que obtengo es:

El tipo double[] debe ser un tipo de valor no anulable para poder usarlo como parámetro ''T''.

La clase donde se almacenan los Data se almacena con éxito en la base de datos y las relaciones con esta clase. Solo me falta la columna de Data .


Nathan White tiene la mejor respuesta (tengo mi voto).

Aquí hay una pequeña mejora con respecto a la respuesta de Joffrey Kern para permitir listas de cualquier longitud (sin probar):

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


No use doble [] use List insted.

Me gusta esto.

public class MyModel{ ... public List<MyClass> Data { get; set; } ... } public class MyClass{ public int Id { get; set; } public double Value { get; set; } }

Toda esa solución que veo allí es mala, porque:

  1. Si crea una tabla, no desea almacenar datos como este: "99.5,89.65,78.5,15.5" ¡eso no es válido! En primer lugar, es una cadena que significa que si puede escribir una letra en el mismo y en el momento en que su servidor ASP.NET llame al doble.Particulará que se producirá FormatException y que realmente no desea.

  2. Es más lento, porque su servidor debe analizar la cadena. ¿Por qué analizar la cadena en lugar de tener casi listos los datos de SQL Server para usar?


Puedes hacer una cosa como esta:

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


Sé que es un poco caro, pero podrías hacer esto

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

Esto ahora asignará una sola entidad (aquí ''Referencia'') a una ''lista'' de su clase Primitiva. Básicamente, esto permite que la base de datos SQL esté contenta y le permita utilizar su lista de datos de manera adecuada.

Es posible que esto no se ajuste a sus necesidades, pero será una manera de hacer feliz a EF.


Sería mucho más fácil si usa List<double> lugar de double[] . Ya tienes una tabla que almacena tus valores de Data . Probablemente tenga una clave externa de alguna tabla a la tabla donde se almacenan sus valores dobles. Cree otro modelo que refleje la tabla donde se almacenan los dobles y agregue asignaciones de clave externa en la clase de asignaciones. De esa manera, no necesitará agregar alguna lógica de fondo compleja que recupere o almacene valores en una propiedad de clase.