web-dev-qa-db-fra.com

Comment stocker le double tableau [] dans la base de données avec l'approche Entity Framework Code-First

Comment puis-je stocker un tableau de doublons dans une base de données en utilisant Entity Framework Code-First sans impact sur le code existant et la conception de l'architecture?

J'ai examiné Data Annotation et l'API Fluent, j'ai également envisagé de convertir le tableau double en une chaîne d'octets et de stocker cet octet dans la base de données dans sa propre colonne.

Je ne peux pas accéder à la propriété public double[] Data { get; set; } avec l'API Fluent, le message d'erreur que je reçois alors est le suivant:

Le type double[] doit être un type de valeur non nullable pour pouvoir utiliser comme paramètre 'T'.

La classe dans laquelle Data est stocké est correctement stockée dans la base de données, ainsi que les relations avec cette classe. Il ne me manque que la colonne Data

20
jonas

Merci à tous pour vos contributions. Grâce à votre aide, j'ai pu trouver le meilleur moyen de résoudre ce problème. Lequel est:

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

Grâce à ces messages stackoverflow: Chaîne vers tableau double et Tableau de doublons vers une chaîne

23
jonas

Vous pouvez faire une chose comme ça:

    [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; }
40
Joffrey Kern

Je sais que c'est un peu cher, mais tu pourrais le faire

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

Cela va maintenant mapper une seule entité (ici "Référence") sur une "liste" de votre classe Primitive. Cela permet essentiellement à la base de données SQL d'être satisfaite et de vous permettre d'utiliser votre liste de données de manière appropriée.

Cela ne vous conviendra peut-être pas, mais ce sera un moyen de rendre EF heureux.

5
Nathan White

Ce serait beaucoup plus facile si vous utilisiez List<double> plutôt que double[]. Vous avez déjà une table qui stocke vos valeurs Data. Vous avez probablement une clé étrangère d'une table à la table où vos valeurs doubles sont stockées. Créez un autre modèle qui reflète la table dans laquelle les doublons sont stockés et ajoutez des mappages de clés étrangères dans la classe de mappages. De cette façon, vous n'aurez pas besoin d'ajouter une logique d'arrière-plan complexe qui récupère ou stocke les valeurs dans une propriété de classe.

4
Husein Roncevic

N'utilisez pas double [], utilisez List insted.

Comme ça.

public class MyModel{
    ...
    public List<MyClass> Data { get; set; }
    ...
}

public class MyClass{
    public int Id { get; set; }
    public double Value { get; set; }
}

Toute cette solution que je vois là est mauvaise, car:

  1. Si vous créez une table, vous ne souhaitez pas stocker des données telles que: "99.5,89.65,78.5,15.5" qui n'est pas valide! Premièrement, c’est une chaîne qui signifie que si vous pouvez taper une lettre et au moment où votre serveur ASP.NET appelle double.Parse, il en résulte FormatException et que vous ne voulez vraiment pas!

  2. C'est plus lent, car votre serveur doit analyser la chaîne. Pourquoi analyser la chaîne plutôt que d'utiliser des données presque prêtes de SQL Server?

1
Pavel B.

Nathan White a la meilleure réponse (obtenu mon vote).

Voici une petite amélioration par rapport à la réponse de Joffrey Kern pour autoriser les listes de toutes longueurs (non testées):

    [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; }
1
Jacob Brewer