IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Insertion dans un SqlFileStream


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut Insertion dans un SqlFileStream
    Bonjour,

    Je suis en train de m'amuser à faire un petit programme de GED, histoire de garder la main sur C# et SQL Server.

    Pour le moment, tout va bien, ça marche à merveille.

    Cependant, je ne suis pas content du tout de la façon dont j'insère le fichier dans la base de données.

    En effet, pour lire le fichier, je récupère son PathName (adresse sur le serveur SQL Server) et je le récupère via un SqlFileStream.
    Ceci permet de faire :
    - Du traitement asynchrone si l'envie m'en prenait
    - De gérer des fichiers volumineux sans devoir les charger en mémoire
    - De gérer des fichiers de plus de 2 Go (bon, ça, à la limite, c'est pas tous les jours qu'on a un document Word qui fait cette taille...)
    - D'utiliser convenablement le type FILESTREAM de SQL Server 2008

    En revanche, pour l'insertion dans la base de données, je n'ai rien trouvé exploitant le FILESTREAM.

    Voici du coup le code que j'ai trouvé sur le net (qui est le même que si je n'avais pas de FILESTREAM), et qui :
    - Ne permet pas de traitement asynchrone
    - Oblige à charger l'intégralité du fichier en mémoire sur le client, puis sur le serveur SQL
    - Limite la taille du fichier à 2 Go
    - Passe outre le flag FILESTREAM de mon champ

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
                        using (SqlConnection cnx = new SqlConnection(@"Server=.\SQLEXPRESS;Database=MagicGED;Trusted_Connection=True;"))
                        {
                            cnx.Open();
                            using (SqlTransaction trans = cnx.BeginTransaction(IsolationLevel.ReadCommitted))
                            {
                                using (SqlCommand cmd = cnx.CreateCommand())
                                {
                                    cmd.Transaction = trans;
                                    cmd.CommandText = "insert into document (id, title, extension, doc) values (default, @title, @extension, @doc)";
                                    SqlParameter pTitle = cmd.CreateParameter();
                                    pTitle.ParameterName = "title";
                                    pTitle.SqlDbType = SqlDbType.NVarChar;
                                    pTitle.Size = 255;
                                    cmd.Parameters.Add(pTitle);
                                    SqlParameter pExtension = cmd.CreateParameter();
                                    pExtension.ParameterName = "extension";
                                    pExtension.SqlDbType = SqlDbType.NVarChar;
                                    pExtension.Size = 10;
                                    cmd.Parameters.Add(pExtension);
                                    SqlParameter pDoc = cmd.CreateParameter();
                                    pDoc.ParameterName = "doc";
                                    pDoc.SqlDbType = SqlDbType.VarBinary;
                                    pDoc.Size = -1;
                                    cmd.Parameters.Add(pDoc);
    
                                    pTitle.Value = fsi.Name;
                                    pExtension.Value = fsi.Extension.ToLower();
                                    using (FileStream fs = new FileStream(fsi.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                                    {
                                        BinaryReader br = new BinaryReader(fs);
                                        pDoc.Value = br.ReadBytes((int)fs.Length);
                                    }
                                    cmd.ExecuteNonQuery();
                                }
                                trans.Commit();
                            }
                            cnx.Close();
                        }
    En gras, la partie qui me donne envie de vomir.

    Comment faire une insertion en utilisant proprement le FILESTREAM ?

    Mon champ Doc est NOT NULL.

    J'ai comme idée de faire comme suit :
    - Insertion de la ligne avec 0x0 dans Doc
    - Lecture de ma ligne insérée
    - Remplacement du contenu du FILESTREAM par mon document

    En suivant la méthode décrite dans cet article :
    http://msdn.microsoft.com/fr-fr/library/cc716724.aspx
    => Paragraphe "Exemple de remplacement de données FILESTREAM"

    En effet, le paragraphe "Exemple d'insertion de données FILESTREAM" ne fait pas du tout ce que je désire, puisqu'il se contente d'inserer dans le FILESTREAM un second document, sans pour autant créer une seconde ligne (du coup, je ne vois pas trop l'intérêt mais bon)

    Y a-t-il une autre manière de procéder ?
    En effet, créer une ligne vide, puis aller la modifier, je trouve ça un peu moyen pour insérer une ligne... Même si je suis dans une transaction, je trouve que ça fait beaucoup d'étapes pour pas grand chose.

  2. #2
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Voici ce que j'ai fait.

    Seulement, je trouve ça vraiment très moyen.

    De plus, contre toute attente, c'est plus lent

    (Mais bon, dans l'attente de mieux, je conserve ça, au moins je limite mon buffer à 1 Mo, ça évite de saturer la mémoire avec des fichiers volumineux...)

Discussions similaires

  1. Réponses: 2
    Dernier message: 01/06/2004, 12h47
  2. Insertion dans fichier texte + rapide que TStringList ?
    Par benj63 dans le forum C++Builder
    Réponses: 8
    Dernier message: 26/02/2004, 11h34
  3. [LG]Tri par insertion dans une liste chainée
    Par mister_dsg dans le forum Langage
    Réponses: 4
    Dernier message: 18/12/2003, 22h34
  4. Insertion dans un fichier xml à partir d'un xsl
    Par alexandre54 dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 21/03/2003, 09h45
  5. Insertion dans un fichier XML
    Par [DreaMs] dans le forum XMLRAD
    Réponses: 4
    Dernier message: 27/02/2003, 17h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo