J'ai un élément de classe qui représente un élément dans une liste. J'ai une fonction informatique qui appelle la procédure stockée qui renvoie des données de données et je dois convertir le jeu de données vers une matrice d'éléments. Voici ce que je fais:
public class Item
{
private string _ItemIdDataName = "item_id";
private string _ItemNameDataName = "item_name";
private string _PriceDataName = "price";
public long ItemId { get; set; }
public string ItemName { get; set; }
public float Price { get; set; }
private Item(DataRow row)
{
if (row != null)
{
ItemId = long.Parse(row[_ItemIdDataName].ToString());
ItemName = row[_ItemNameDataName].ToString();
Price = float.Parse(row[_PriceDataName].ToString());
}
}
public Item[] load()
{
DataTable dt=DBHandler.GetItems();//Stored procedure that returns DataTable
Item[] items = new Item[dt.Rows.Count];
for (int i = 0; i < dt.Rows.Count; i++)
{
items[i] = new Item(dt.Rows[i]);
}
return items;
}
}
4 Réponses :
Si vous ne l'utiliserez que une fois probablement bien, mais si vous le ferez beaucoup, vous devriez essayer de faire des choses plus génériques. J'ai écrit un article de blog sur la façon d'écrire une méthode d'extension pour MAINTENANT Vous pouvez simplement appeler P> datatable code> qui crée une liste d'objets. Il fonctionne selon la convention selon laquelle les propriétés de l'objet doivent avoir le même nom que les colonnes de la procédure stockée (je modifierais le nom dans la procédure stockée si je pouvais): var mappings = new Dictionary<string,string>();
mappings.Add("ItemId", "item_id");
mappings.Add("ItemName ", "item_name");
mappings.Add("Price ", "price);
var items = dt.ToList<Item>(mappings);
Merci ... J'essayais de garder cela simple, et ce n'est pas si difficile de faire correspondre vos propriétés d'objet contre les colonnes de la procédure stockée :).
Ici, vous supposez que les noms de champs de DB sont égaux aux noms des membres. Ce qui n'est pas toujours vrai. Ai-je tort?
Vous êtes 100% correct et je le dit donc dans la réponse. Lorsque j'ai implémenté cela, j'ai essayé de conserver les propriétés d'objet alignées sur le nom des colonnes pour faciliter la tâche et fonctionnait parfaitement. Si ce n'est pas le cas, vous pouvez modifier la méthode d'extension pour prendre également un dictionnaire dictionnaire
C'est vraiment sympa mais n'est-ce pas vraiment lent selon le code que j'ai écrit?
Il est probablement plus lent oui, mais avez-vous un problème de performance? Gardez-le aussi longtemps que possible, puis optimisez-vous dans ces endroits où vous devez optimiser.
Merci, ça m'aidait. S'il vous plaît corriger: Propriété.sevalue (article, convert.Changetype (rangée [mappings [prope rténame]], Propriété. Propertytype), Null);
@Naor: Cela ne devrait pas être nécessaire ... La méthode SetValue code> doit gérer cela. Avez-vous eu une erreur à ce sujet? Quelle erreur?
@Tomas Jansson: Tomas, je reçois une erreur lorsqu'il tente de convertir célibataire en double ou quelque chose comme ça. Dans la DB, le champ est flotté. De cette façon fonctionne bien. BTW, savez-vous comment cela fonctionnera-t-il avec Enums en tant que type de champ (DB Pass le nom de la valeur ENUM)?
@Naor: Le problème est que vous avez eu une inadéquation de type. Vous pouvez retourner dans l'ancienne solution et au lieu d'avoir un flotteur dans votre objet, le double (le double est plus courant que celui que flotteur). Ce que vous faites maintenant peut faire une erreur car les données de la base de données sont de type double, c'est-à-dire avoir 64 bits, mais votre flotteur n'a que 32 bits, de sorte que si la valeur de la base de données est trop importante, vous pourriez obtenir une erreur. .. Je ne sais pas quoi cependant. Donc, remplacez-vous à ce que vous aviez et utilisez le double de votre objet. En outre, cela pourrait fonctionner avec Enums ... Essayez-le et laissez-moi savoir :).
@Naor: Il suffit d'essayer l'ENUM et cela fonctionne aussi longtemps que l'ENUM est stocké comme une INT dans la base de données.
@Tomas Jansson: Qu'est-ce que vous avez dit, c'est que le flotteur sur la base de données est double sur le client? Puis-je utiliser Enum comme chaîne et pas int?
@Naor: Ce que je dis, c'est que vous avez à pratiquement une double type dans dB, mais seulement un flotteur dans le client (ou que dit votre exemple de code). Changer Prix de flotteur public {obtenir; ensemble; } code> à double prix public {obtenir; ensemble; } code> et modifiez également votre ancien code et tout ira bien. Enums stockés dans la base de données fonctionnera bien S'ils sont INT B>, String Enums ne fonctionnera pas avec cette mise en œuvre, mais il est probablement possible d'étendre la solution pour permettre cela aussi.
@Tomas jansson: en supposant que j'utilise ceci: Propriété.sevalue (article, convert.Changetype (rangée [mappings [propice rténame]], Propriété. degré de propriété), Null); Qu'est-ce qui ne va pas ou différent de votre approche?
@Naor: Comme je l'ai dit plus tôt, cela fonctionnera même pour Float-> Double ... et je ne pense pas que ce n'est pas bon depuis double> flotteur (double: 64 bits, flotteur: 32 bits). De plus, cela sera encore plus lent :), la convertie le convertira et SetValue l'analysera une fois de plus. Bien sûr, cela fonctionne, mais j'irais pour ma solution :). Moins de code aussi.
@Tomas Jasson, j'ai posé une autre question (liée) que vous pourriez être intéressée.
@Sblacker, où est le lien?
Belle réponse, mais méfiez-vous des propriétés sans setters publics! Voir: Stackoverflow.com/Questtions/2811198/...
assez bon, mais j'ai quelques suggestions:
Ne pas lancer de choses pour être racheté à un autre type. Cette peut causer la corruption de vos données type, et est lent / inefficace. p> li>
Attendez-vous et vérifiez que NULL vient de SQL Server. P> LI> ul>
donc, au lieu de: p> Essayez: p> (Ajouter une référence au système .Data.DataSetExtensions Pour obtenir l'extension de champ) P> P>
Votre constructeur d'élément privé et votre Vous savez, une classe devrait faire une chose et une chose bien. P>
Essayez de Charger () code> Les fonctions ne semblent pas article code> classe. P>
1. Refacteur de l'établissement privé C'TOR à une classe d'assistance qui a simplement analysé le datarow et renvoie une instance d'article
2. et refacteur le charge () code> dans une autre classe qui utilise simplement la méthode d'assistance ci-dessus et renvoie une gamme d'instances d'objet d'élément p>
Cette façon me fera créer de nombreuses classes. Je veux mettre les choses ensemble s'il y a une connexion. J'ai manqué de noms aux cours ..
@Naor: Je ne réponds que de répondre à vos principales questions;)
travail parfait pour automapper . P>
Deux exemples: P>
http://house9.blogspot.com/2010/ 11 / Automapper-DataTable-to-List.html P>
@Naor en effet - mais cela a été posé bien après que MODApper existait, ce qui vous apparaît toujours dans Google Recherches à la recherche d'une réponse. Stackoverflow est destiné à trouver les meilleures réponses, pas pour assurer la conversation les attachées bien et est ensuite fermée - si c'est ce que vous vouliez, utilisez Google Groupes.
Pourquoi
charge () code> intermédiaire de classe d'élément?Parce qu'il semble très signifié de le mettre sous différentes classes. J'ai de nombreux cas comme celui-ci et je ne peux pas avoir de centaines de classes qui ne renvoie que le résultat de la requête.
@Naor rend le statique au moins ..