Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

60 commentaire(s) de Malkuth sur des sources sur tout CodeS-SourceS

Le : 31/03/2009 11:39:46
Source : "SURFACE LIKE" EN SILVERLIGHT
Il n'a actuellement aucun commentaire, je considère cette source comme non terminer tant que je n'aurais pas réussi à régler le problème de TemplateBinding, si vous avez idée de se qui pose problème, n'hésité pas à m'en faire part!

Il y'as 2 projet, Malkuth.Controls qui contient les contrôles Surface et SurfaceItem, l'autre projet est une petite application pour montrer l'utilisation et la facilité a intégré des éléments très divers dans les SurfaceItem.


Le : 27/02/2009 20:00:17
Source : SPLIT SQL SANS TABLE TEMPORAIRE
Voilà un exemple complet avec implémantation du IDatareader :
http://www.csharpfr.com/codes/BULKINSERT-CSHARP_49377.aspx


Le : 27/02/2009 16:59:28
Source : SPLIT SQL SANS TABLE TEMPORAIRE
Le cross aplly est effectivement trés pratique mais je doute vraiment que les performances soient au rendez vous.

sur 10 000 000 de lignes traitée la charge de travail deviens vraiment colosale et je crois que chaque partie d'un produit doit être utilisé pour ce qu'il sait le mieux faire, et pour moi C# est bien plus performant en transformation linéaire de donnée que SQL Serveur.

Sle projet avais été pure SQL pourquoi pas (enfin je pense que TheOnlyMaX à une solution plus performante) mais étant donnée qu'il nous présente un code C# j'en conclu qu'il a donc du C# dans son projet donc autant l'utiliser là ou il est mieux indiquer...

@TheOnlyMaX : serait'il possible que tu me passe un de tes fichiers d'importation type? (un Fake bien entendu) avec la table dans laquelle les données sont placé au final(déclaration SQL) afin de consolidé mon code pour un cas réaliste? pour infos je suis à un temps de 11 sec de traitement pour lecture/néttoyage/vérification métier sur un fichier de 10 000 000 de ligne et 3 colones (reste a traiter le bulkinsert en lui même) et ce code est trés loin d'un code optimisé.


Le : 27/02/2009 12:51:00
Source : SPLIT SQL SANS TABLE TEMPORAIRE
Alors en fait, si tu baisse la valeur, c'est aussi baisser l'intêret du bulkcopy (aprés on peu tester différentes valeurs et en trouver une correct dans ton cas de maniére empirique).

Ensuite, ce code peux êtres déployé sur une autre serveur donc on déplace le probléme de charge mémoire/Travaille vers une machine qui n'auras pas la même importance dans le process glabal (voir dédier).

enfin, comme je le disait dans le dernier commentaire la fonction de transfert au serveur accept les interface IDatareader, celle ci représente un flux de lecture de donnée en avant uniquement, elle n'as donc pas besion de "Buffériser" les données, en gros pour expilquer l'interface:

une fonction ReadNext qui avannce d'une ligne le flux.
des fonction GetInt32(int col)/GetString(int col)/... qui lise la donnée de la [col] dans la ligne courante.
plusieur fonctions qui permette de gérés les métadonnée(nom de colone,type des colones etc.

En utilisant les fonction précédante et en les encapsulant dans une classe implémantant cette interface, on peu arrivé a ne jamais avoir plus d'une ligne de donné en mémoire.

Attention, en disant cela jetiens a présisé que je ne connait pas le fonctionnement interne de l'objet SqlBulkCopy, a t'il un buffer interne? a voir... un point important aussi, il faut bien pensé paramettré le Timeout car si l'opération est longue celui ci est vite dépassé et mettre une valeur trop longue peux complétement bugé le tout.

Enfin l'objet SqlBulkCopy posséde plusieur constructeur simpathique dont notement un constructeur permetant de spécifier une transaction et les option de Bulk (déclanchement des triggers,gestion des NULL/AutoIncrément etc, ce qui le rend particuliérement complet.

Un dernier point intérréssant de cette technique est sa souplesse il est trés facile d'introduire plusieurs couches de travaille intermédiare et de faire un code trés modulaire. ex :

Ajout d'un process de validation Métier:

public IEnumerable<donnéestructurées> ValidationMetier IEnumerable<donnéestructurées> donnéesavérifier)
        {
            foreach (donnéestructurées lignepropre in donnéesavérifier)
            {
                if (lignepropre.col_age < 10
                || lignepropre.col_age > 20
                || string.IsNullOrEmpty(lignepropre.col_nom))
                    // si ca va pas on reprend le traitement a la ligne suivante
                    continue;

                //Si tout va bien on envoie la ligne propre et on continue ;)
                yield return lignepropre;
            }
        }

Ce qui permet maintenant de faire :

Insererligne(ValidationMetier(nettoyerlignes(lireLignes("monfic.csv"))));

Maintenant, admettons que le fichier de départ est maintenant un XML :

public IEnumerable<donnéestructurées> LireDonnéesXML(string fichierxml)
{
....
yield return ...;
....
}

On peut mtn faire :
Insererligne(ValidationMetier(LireDonnéesXML("monfic.xml")))



La ca devient trés simpa car on a pu reprendre facilement le code commun sans ce prendre la tête et en gardant une compatibilité avec l'ancien code qui peut toujours servir si les deux type de fichier sont utilisé...

Enfin cette maniére de faire permet trés facilemet de test chaque fonction hors context et de valider son process:

public IEnumerable<string> fauxlecteur()
{
    yield return "Tom;10;";
    yield return "Rom;20";
    yield return "Tiemh";
}
public void VérificationNetoyage(IEnumerable<donnéestructurées> données)
{
    IEnumerator<donnéestructurées> enum = données.GetEnumerator();

    if(!enum.MoveNext()) throw new Exception();
    if(enum.Current.col_nom!= "Tom") throw new Exception();
    if(enum.Current.col_age!= 10) throw new Exception();

    if(!enum.MoveNext()) throw new Exception();
    if(enum.Current.col_nom!= "Rom") throw new Exception();
    if(enum.Current.col_age!= 20) throw new Exception();

    if(enum.MoveNext()) throw new Exception();
}

maintenant si on fais : VérificationNetoyage(nettoyerlignes(fauxlecteur())); et qu'on obtient une exception alors le nétoyage ne fonctionne pas comme on l'attendrais!


Vu que ca à l'air de plaire, je vais trouvé un peux de temps se weekend pour faire une source d'exemple complette.


Le : 27/02/2009 09:04:15
Source : SPLIT SQL SANS TABLE TEMPORAIRE
en fait on remarque que le WriteToServeur peut aussi utilisé une interface IDataReader en paramêtre, donc pour allez un peu plus loin le mieux serais d'encapsuler les 2 fonctions dans une classe implémentant IDataReader ce qui évite de se retrouver a gérer un buffer en DataTable (j'ai horreur de ces objets DataRow/DataTable etc...) et la on aurais vraiment un programm entiérement "A la Volé" mais bon cette interface est un peu longue a implémenter pour un commentaire...peut être un code prochain.


Le : 26/02/2009 22:22:29
Source : SPLIT SQL SANS TABLE TEMPORAIRE
oups, aprés la boucle foreach dans Insererligne il manque :

                        if((nblignes%100000)!=0)
                            cpy.WriteToServer(donnéespretes);


Le : 26/02/2009 22:18:48
Source : SPLIT SQL SANS TABLE TEMPORAIRE
Lecture/ nétoyage à la volé ca veut dire en gros tu lis une ligne du fichier, tu la notoie aussitôt et tu la transmet au serveur.

donc, lire une à une les ligne d'un fichier texte ca donne un truc du genre :

        public IEnumerable<string> lireLignes(string cheminfichier)
        {
            string ligne;
            using (TextReader txtstrm = File.OpenText(cheminfichier))
                while ((ligne = txtstrm.ReadLine()) != null)
                    yield return ligne;
        }

ensuite on doit les néttoyé on va séparé ca en 2 phases : l'extraction des données puis leur vérification pour des d'optimisation certain les 2 étape peuvent être plus ou moins mélé, au passage on crée une petite structure légére pour conservé les donnée nétoyé (et typé d'ailleurs...)


        public struct donnéestructurées
        {
            public string col_nom;
            public int col_age;
        }


        public IEnumerable<donnéestructurées> nettoyerlignes(IEnumerable<string> lignesbrute)
        {
            foreach (string ligne in lignesbrute)
            {
                donnéestructurées lignepropre = new donnéestructurées();

                //extraction des données
                string[] donnesintermediaire = ligne.Split(';');
                if (donnesintermediaire.Length != 2) continue;// si ca va pas on reprend le traitement a la ligne suivante
                lignepropre.col_nom = donnesintermediaire[0];
                int.TryParse(donnesintermediaire[1],out lignepropre.col_age);

                //Vérification de la bonne conformitée des données
                if (lignepropre.col_age < 10
                || lignepropre.col_age > 20
                || string.IsNullOrEmpty(lignepropre.col_nom))
                    // si ca va pas on reprend le traitement a la ligne suivante
                    continue;

                //Si tout va bien on envoie la ligne propre et on continue ;)
                yield return lignepropre;
            }
        }

maintenant, on a donc moyen des récupéré des donnée propres juste en faisant:

nettoyerlignes(lireLignes("monfic.csv"));

(je ne sais pas ta connaissance éxacte de C# mais si tu fais une exécution pas à pas de ce code tu véras que contrairement au aparance, il lit une ligne, la nétoi, lit la suivante, la nétoi etc, si ce mécanisme t'est inconnue renseigne toi sur le mot clef yield, si connais déjà tout ca, oublie mon commentaire ;) )


alors maintenant on as des donnée propre, il faut les envoyés au serveur, solution un, une suite d'insert, a oublier dans ton cas on est bien d'accord, Solution 2, envoyé les donnée sous forme XML trés bien pour un volume moyen mais pas assez rapide pour 10millions de lignes ^^ solution 3 le Bulk insert (ouai on est d'accord ^^) et pour le bulkinsert y'a une classe pas mal foutu en .NET : System.Data.SqlClient.SqlBulkCopy

ca permet d'accéder a la plupart des fonctionnalité  de Bulkinsert directement depuis le code(donc sans avoir besiion de réécrire les données dans un fichier.

voici un exemple


        public void Insererligne(IEnumerable<donnéestructurées> données)
        {
            using(SqlConnection con = new SqlConnection("maconnexion"))
            {
                using (SqlBulkCopy cpy = new SqlBulkCopy(con))
                {
                    cpy.BulkCopyTimeout = 100000;
                    cpy.BatchSize = 100000;
                    cpy.DestinationTableName = "matablefinal";
                    cpy.ColumnMappings.Add("col_nom", "Nom");
                    cpy.ColumnMappings.Add("col_age", "Age");

                    DataTable donnéespretes = new DataTable();

                    DataColumn cNom = new DataColumn("col_nom", typeof(string));
                    donnéespretes.Columns.Add(cNom);

                    DataColumn cAge = new DataColumn("col_age", typeof(int));
                    donnéespretes.Columns.Add(cAge);
                    int nblignes = 0;
                    foreach (donnéestructurées donné in données)
                    {
                        DataRow row = donnéespretes.NewRow();
                        row[cNom] = donné.col_nom;
                        row[cAge] = donné.col_nom;
                        donnéespretes.Rows.Add(row);

                        if((nblignes%100000)==0)
                            cpy.WriteToServer(donnéespretes);
                    }
                }
            }
        }

donc maintenant tu fais : Insererligne(nettoyerlignes(lireLignes("monfic.csv")));
et ca roule.

Le code es pas optimiser pour 2 sous mais même en l'état il doit être bien plus performant.


Le : 26/02/2009 18:37:27
Source : SPLIT SQL SANS TABLE TEMPORAIRE
Je rejoins tmcuh, je pense que la método n'est pas optimal(mais on as pas forcerment toute les infos...)

a lors actuel tu fais :
BulkInsert d'un CSV en table intermédiaire
Nettoyage/insertion final

Clairement SQL n'est pas le meilleur choix pour le nétoyage(qq bench pourrons facilement le prouver).

je pense que tu aurais plutot du utilisé la métho suivante :
Lecture/Nétoyage du CSV (netoyage a la volée)
bulkinsert dans la table final.

tu dispose de la classe [System.Data.SqlClient.SqlBulkCopy] qui permet de commander facilement l'insertion Bulk directement depuis C#.

D'abord ca me semble plus logique et surtout, Ca permet de déporter la charge de nettoyage sur une machine différente (voir plusieurs...)


Le : 19/11/2008 07:27:30
Source : UNE CLASSE POUR GÉREZ LES REQUETTES POST SUR SERVEUR HTTP [.NET 2.0]
Je vais essayer de me dégager un peu de temps se weekend pour mettre un peu a jour cette source et prendre en compte tes ajout, concernant l'encodage, je ne suis convaincu ni par le UTF8 ni par le et moins encore par le default qui risque d'être génant lors d'échange avec des system reposant sur d'autre encodage (unix/linux notament), en fait je pense rajouter un propriéter encoding sur le constructeur se qui me déchargeras de toute "responsabilitée" et rendra le code plus maléable :p

je vais aussi supprimer les Encoding.GetBytes(...) qui oblige a maintenir en mémoire des tableau d'octets volumineux l'utilisation de TextWriter seras a la fois plus eficace plus simple et finalement plus compréhensible.


Le : 13/05/2008 19:04:09
Source : CONTRÔLER LA SAISIE D'UN E-MAIL
par expression réguliére on peut faire comme ceci :
( code en .NET )
Imports System.Text.RegularExpressions
Module Validation
    Const AutorizedMailCharPattern = "[a-z0-9_]";
    Const ValidMailPattern = "^#+(\.#+)*@#+(\.#+)*?\.#{2,4}$";
    Dim RX_MailCheck As New Regex(ValidMailPattern.Replace("#",AutorizedMailCharPattern,RegexOptions.Compiled Or RegexOptions.IgnoreCase));

    Function IsEmailValid(Email As String) As Boolean
        Return RX_MailCheck.IsMatch(Email);
    End Function

End Module

Je suis désolé de présenté se code en .Net, toutefois je suis persuadé que les expressions réguliéres existe en VB et la syntaxe doit être sufisement proche pour que l'exemple soit retenu.

On voit d'emblé que le code est bien plus simple que les codes sans expression réguliére, il est aussi trés rapide (en fait il pourais bien être plus rapide que le code sans expression réguliére, il prend de nombreux cas en compte dont certain ne sont pas envisagé dans les codes précédent.

Je post ceci afin de popularisé un peu les expressions réguliéres, certains les connaissent trés bien mais beaucoup ignore tout de leur puissance, elles sont pourtant un outil incontournable dans la validation de données...



1 2 3 4 5 6


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,203 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.