10
votes

C # - Idatareader à la cartographie d'objet à l'aide de génériques

Comment mapper un objet DigneAreader dans un objet de classe à l'aide de génériques?

Par exemple, je dois effectuer ce qui suit: p> xxx pré>

et plus tard j'ai besoin de Appelez cette méthode de classe comme suit: P>

IDataReder dataReader = DBUtil.Fetchdata("SELECT * FROM Book");

List<Book> bookList = Mapper<Book>.MapObject(dataReder);

foreach (Book b in bookList)
{
     Console.WriteLine(b.ID + ", " + b.BookName);
}


10 commentaires

Une suggestion - lisez dans un iEnumerable avec une déclaration de rendement.


// la cartographie va ici, exactement ce que je t'ai montré dans ma réponse, vous pouvez mapper n'importe quel objet sur le lecteur de données (plus précisément: injecter des valeurs d'un idatreader dans un objet n'importe quel type)


Pourquoi n'utiliseriez-vous pas un orateur dédié alors? Un micro-orme comme Dapper semble être un bon ajustement ici.


@nawfal, a été posée en juillet 2009.


@Bry Honnêtement, avec des commentaires, des réponses, etc. Les futurs visiteurs sont également pris en compte. Et ce n'est pas comme les ormes n'existaient pas en 2009 :)


@nawfal, alors pourquoi ne proposez-vous pas une prime pour mettre à jour la réponse?


@Broy Il y a des tonnes de questions sur le même sujet et je suis sûr qu'elle est répondue ailleurs. Un tel: Stackoverflow.com/questions/19841120/... < / a>. Comme je l'ai dit, vous pouvez utiliser un micro-orme. Dapper fait cela.


@nawfal, est-ce que l'excuse pour ne pas offrir une prime, ou une preuve que la question était inutile? Le lien que vous avez montré a été posé en 2013.


Laissez-nous Continuez cette discussion en chat .


Related: Stackoverflow.com/Questtions/812034/...


10 Réponses :


2
votes

Eh bien, je ne sais pas si cela correspond ici, mais vous pouvez utiliser le mot-clé de rendement xxx


2 commentaires

+1 utilisation intéressante de di. Il serait agréable d'avoir le type T fournir la mise en œuvre de ConvertFunction également. :RÉ


C'est bien di et il peut être combiné à la solution d'OMU.



1
votes

Vous pouvez utiliser cette classe d'ébriété lateuse I écrivée: http://codecube.net/2008 / 12 / Nouveau-Datebinder / .

J'ai écrit un autre message avec l'utilisation: http://codecube.net/2008 / 12 / Utilisation-la-déchieur /


0 commentaires

1
votes

Cela va être très difficile à faire pour la raison pour laquelle vous essayez essentiellement de cartographier deux inconnues ensemble. Dans votre objet générique, le type est inconnu et dans votre digne d'information, la table est inconnue.

Donc, ce que je voudrais suggérer, c'est que vous créez une sorte d'attribut de colonne à joindre aux propriétés de votre entité. Et ensuite regarder à travers ces attributs de propriété et essayer de rechercher les données de ces attributs dans la DigneAreader.

Votre plus gros problème va être, que se passe-t-il si l'une des propriétés n'est pas trouvée dans le lecteur, ni vice-versa, l'une des colonnes du lecteur n'est pas trouvée dans l'entité.

Bonne chance, mais si vous voulez faire quelque chose comme ça, vous voulez probablement une orje ou au moins une sorte de mise en œuvre active des enregistrements.


1 commentaires

regarde ma réponse, ce n'est pas si difficile :), et il n'y a pas d'attributs requis



1
votes

La manière la plus simple que je puisse penser à Porthant serait de fournir un délégué Func pour convertir chaque colonne et construire votre livre.

Alternativement, si vous avez suivi certaines conventions, vous pouvez potentiellement gérer cela par réflexion. Par exemple, si chaque colonne s'est mappée sur une propriété dans l'objet résultant en utilisant le même nom, et que vous avez restreint T dans votre mappeuse pour fournir un T constructible, vous pouvez utiliser la réflexion pour définir la valeur de chaque propriété sur la valeur correspondante de la colonne correspondante. .


0 commentaires

1
votes

Je ne pense pas que vous puissiez vous contenter de définir la relation entre les champs sous une forme. Jetez un coup d'œil à cet article et faites attention à la définition de la cartographie, cela peut fonctionner pour vous.

http://www.c-sharpcorner.com/uploadfile /RMCOCHRAN/ELGANT_DAL05212006130957PM/ELGANT_DAL.ASPX


0 commentaires

1
votes

Quoi de quoi suivre

abstract class DataMapper
{
    abstract public object Map(IDataReader);
}

class BookMapper : DataMapper
{
   override public object Map(IDataReader reader)
   {
       ///some mapping stuff
       return book;
   }
}

public class Mapper<T>
{
    public static List<T> MapObject(IDataReader dr)
    {
        List<T> objects = new List<T>();
        DataMapper myMapper = getMapperFor(T);
        while (dr.Read())
        {
            objects.Add((T)myMapper(dr));
        }

        return objects;
    }

    private DataMapper getMapperFor(T myType)
    {
       //switch case or if or whatever
       ...
       if(T is Book) return bookMapper;

    }
}


1 commentaires

Vous pourriez éviter les conditions si sinon et compter sur le polymorphisme à condition que la classe de livre elle-même implémente certains Func .



3
votes

J'utilise ValueInjecteur pour ce

Je fais comme ceci: p> xxx pré>

Vous aurez besoin de cette valorisation pour que cela fonctionne: P>

public class DataReaderInjection : KnownSourceValueInjection<IDataReader>
    {
        protected override void Inject(IDataReader source, object target, PropertyDescriptorCollection targetProps)
        {
            for (var i = 0; i < source.FieldCount; i++)
            {
                var activeTarget = targetProps.GetByName(source.GetName(i), true);
                if (activeTarget == null) continue;

                var value = source.GetValue(i);
                if (value == DBNull.Value) continue;

                activeTarget.SetValue(target, value);
            }
        }
    }


4 commentaires

Est-il quelque part une bibliothèque d'injections courantes et utiles?


@PavelHodek Il n'y a pas de bibliothèque, mais il y en a beaucoup dans la solution de démonstration principale de ValueInjectTer et dans les pages Codépleplex


Quelques choses. 1) Vous utilisez la réflexion pour définir la valeur, c'est mauvais pour la performance. Go Expression Route. 2) Où est DataReaderInjection et connuSourceValueunjection dans votre bibliothèque? Je pense que vous avez changé de noms depuis cette réponse? 3) Est-ce qu'il utilise la réflexion dans les coulisses à chaque fois dans la même boucle de lecture.Read pour obtenir des noms de propriété? J'espère que non, mais je ne peux pas me convaincre sans voir la classe connueValueValueInjection.


4) Ceci est mineur mais toujours - vous n'abandonnez pas à la propriété lorsqu'il s'agit de NULL dans la base de données (cas DBNULL), mais si une valeur est attribuée à cette propriété lorsqu'elle est nouvelle-ing dans le constructeur, comme "Var O = Nouveau Utilisateur()"? Dans ce cas, l'utilisateur que vous revenez sera différent de ce qui est réellement présent dans la DB.



1
votes

Qu'en est-il d'utiliser fluent ado.net ?


0 commentaires

1
votes

0 commentaires

1
votes

Je recommanderais que vous utilisiez automapper pour cela.


0 commentaires