Cette discussion est consacr�e � l'article intitul� "Quelle est la diff�rence entre un DTO et un POCO ?" qui est la traduction d'un article de Rudy Lacovara.
Postez ici vos commentaires concernant cette publication.
![]()
Cette discussion est consacr�e � l'article intitul� "Quelle est la diff�rence entre un DTO et un POCO ?" qui est la traduction d'un article de Rudy Lacovara.
Postez ici vos commentaires concernant cette publication.
![]()
Excellent article ! tr�s utile. Maintenant, j'ai une petite question :
Quid du DTO pour lequel on est oblig� d'ins�rer la logique de s�rialisation car il impl�mente IXmlSerializable ? c'est un DTO, un POCO, ni l'un ni l'autre ?
Sinon, concernant les diff�rents sch�mas d'implantation, en voici un que j'utilise tous les jours :
J'ai ma couche d'acc�s aux donn�es branch�e via l'ORM Entitiy Framework.
J'ai donc une partie DAL me permettant d'effectuer les requetes linq to entities.
Ensuite, j'ai une parti BLL qui me permet de faire tous les mix de requetes dont j'ai besoin et ressortir un r�sultat m�tier.
Entre la DAL et la BLL, je transforme (de fa�on bilat�rale) mes Entities en DTO et inversement.
Le tout est au final utilisable avec n'importe quel projet et peut m�me etre partag� entre projets de types diff�rents.
Dans mon cas, j'ai branch� un webservice WCF � la BLL et il va y avoir une partie ASP.Net MVC2 qui viendra plus tard se brancher sur cette meme BLL.
Ce qu'il y a d'int�ressant avec les DTO, c'est que derriere ils peuvent �tre import�s dans tous les projets se servant de ma BLL (ou meme de mon webservice).
En tout cas, merci pour l'explication![]()
chez moi toutes les couches d'une application ont acc�s aux DTO , seul la couche "business" a acces aux POCO ( ou pojo , etc ... ).
un POCO est forc�ment li� au business layer,puisqu'il a un comportement.
Un DTO peut par contre alimenter un template , le mod�le , ou n'importe quoi d'autre.
Article clair et didactique !
Je viens donc de r�aliser que je suis depuis plus de dix ans un M. Jourdain du POCO/DTO.![]()
Dites moi, dans vos projets, comment faites vous la translation POCO<->DTO ?
Avez vous des petits outils, des patterns ou autres qui permettent d'automatiser un peu la transformation ? ou bien g�rez vous la copie des propri�t�s � la mano ?
Qu'entends-tu par translation/transformation ?
Le lien entre un DTO et son POCO correspondant est qu'un POCO a un DTO, les propri�t�s ne sont pas "copi�es" :
Les propri�t�s du DTO sont accessibles dans le POCO via la propri�t� Data.
Code C# : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11 public class PersonDTO { // Propriétés du DTO... } public class PersonPOCO { public PersonDTO Data { get; set; } public PersonPOCO(PersonDTO dto) { this.Data = dto; } }
Voir l'h�ritage "a un", dans le paragraphe "Alors qu'est-ce qu'un POCO ?"
Je me joins aux autres pour te f�liciter de ton choix de traduction, l'article choisi est excellent, et la traduction de qualit�
bravo![]()
Confront� � un probl�me d'architecture, je me suis pench� sur cet article.
Et je me demande comment g�rer la composition/agr�gation dans ce mod�le ?
En effet, mes objets ont quelques propri�t�s de type primitif, mais aussi un gros paquet d'instances, voire de collections, d'autre classes.
Pour �tre pr�cis sur ma question : � quel niveau g�re-t-on la composition ?
Au niveau des POCO tu peux utiliser tous les concepts de la POO sans probl�mes mais pour les DTO tu peux aussi le faire mais il faut avant tout savoir que les DTO c'est pour faire transiter des donn�es �tre un pont entre deux parties ou doit contenir des informations minimalistes dont on a besoin quand on travaille par exemple avec des services telles que WCF. Bref un DTO ne doit pas contenir la complexit� de ton mod�le ou domaine. Si tu te mets � te poser des questions de composition exc�dant deux niveaux alors l� je ne vois plus l'int�r�t d'utiliser les DTO autant utiliser directement ton mod�le pour ne pas avoir � tout le recr�er en int�grant sa complexit� dans les DTO.
Hello,
Comme tout le monde l'a d�j� dit, il s'agit l� d'un excellent article (comme tous les autres (ou presque) du m�me auteur).
Par contre cela me pose un souci.
Avant, la couche BLL passait directement les DTO ou les listes de DTO � la couche GUI qui les utilisait et les renvoyait vers BLL.
A la lumi�re de cet article, GUI utilise maintenant des objets de la BLL (des POCO donc) qui contiennent les DTO.
Mais du coup, comment on fait pour affecter les propri�t�s DisplayMember et ValueMember des classes du genre ComboBox ou ListBox (pour DisplayMember, j'ai trich� en surchargeant la m�thode ToString du POCO mais c'est du bricolage non ?)
Et je n'ai pas encore test� mais j'imagine que je vais avoir le m�me probl�me pour affecter la propri�t� DataPropertyName de la classe DataGridViewColumn.
Comme faites-vous donc ?
Salut,
Dans notre projet (Silverlight / WCF) on avait cette probl�matique �tant donn� que le fait de recevoir d'une part, une liste de DTO pour alimenter l'itemssource du combobox et, d'autre part, le DTO correspondant � l'�lement actuellement s�lectionn� via le webservice faisait que les deux DTO identiques (celui qui est la s�lection courante et celui qui fait partie de la liste et qui en base correspondent a la meme ligne) n'avaient pas la meme adresse m�moire.
Du coup, en surchargeant la m�thode Equals pour faire matcher les property Id plutot que les r�f�rences m�moire a r�solu le probl�me.
Euh... J'ai pas compris![]()
Comment utilises tu ta combo, peux tu envoyer un exemple ? parce que je ne sais meme pas dans quel type de projet tu bosses (winforms, wpf, silverlight, win8, wp8 ?)
Je fais du winforms.
Mais je pense que je faisais de la merde (j'ai contourn� le probl�me en faisant autrement et �a va mieux maintenant ^^).
Exemple de ce que je faisais :
J'avais un poco Person avec une propri�t� DTO as PersonDTO et un poco Persons qui h�ritait de List(Of Person).
Du coup, dans la GUI, j'utilisais des objets du type Persons pour manipuler des listes. Mais ce genre de truc, c'est pas pratique � passer en datasource.
Maintenant, le poco Persons n'h�rite plus de List(Of PersonDTO) mais a une propri�t� DTO as List(Of PersonDTO). Et �a va tout de suite mieux ^^
D�sol� de d�terrer ce topic que je d�couvre tardivement.
Est-ce que par hasard un d�veloppeur fain�ant comme moi aurait cr�� un outil pour automatiser la cr�ation des classes d�crites dans cet article tr�s int�ressant pour une base de donn�es enti�re ?
Qui ne tente rien n'a rien![]()
Il y a des outils qui existent d�j� comme entity framework mais personnellement, je n'aime pas.
Dans mon ancien taff, j'avais d�velopp� �a en me basant sur le catalogue de la db relationnelle utilis�e mais cela n�cessite d'avoir une db fortement normalis�e pour avoir quelque chose de propre. Ca m'avait pris 1/2 journ�e pour avoir qqch de fonctionnelle donc rien d'insurmontable![]()
Justement le but est de ne pas utiliser EF, que je connais mal, mais que beaucoup de d�veloppeurs n'aiment pas, s�rement pour de bonnes raisons.
Du coup j'ai trouv� un script pour cr�er les DTO � partir de la base de donn�es.
Code SQL : 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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 DECLARE @Schema VARCHAR(MAX) = N'dbo' DECLARE @TableName VARCHAR(MAX) = N'ENT' DECLARE @Namespace VARCHAR(MAX) = N'MonApplication.DTO' DECLARE @Chemin VARCHAR(MAX) = 'C:\MonApplication\' + @TableName + '.cs' DECLARE @CRLF VARCHAR(2) = CHAR(13) + CHAR(10); DECLARE @result VARCHAR(max) = ' ' DECLARE @constructor VARCHAR(max) = ' ' DECLARE @PrivateProp VARCHAR(100) = @CRLF + --' /// <summary>' + @CRLF + --' /// ' + @CRLF + --' /// </summary>' + @CRLF + CHAR(9) + CHAR(9) + 'public <ColumnType> <ColumnName> { get; set; }' + @CRLF; DECLARE @LigneAffectation VARCHAR(100) = ' <ColumnName> = CommonBase.<ColumnType>;' + @CRLF; SET @result = 'using System;' + @CRLF + @CRLF + 'using MonApplication.COMMON;' + @CRLF + @CRLF + 'namespace ' + @Namespace + @CRLF + '{' + @CRLF + --' /// <summary>' + @CRLF + --' /// ' + @CRLF + --' /// </summary>' + @CRLF + ' public class ' + @TableName + ' : DTOBase' + @CRLF + ' {' + @CRLF + ' #region Instance Properties' + @CRLF SET @constructor = '///<summary>' + @CRLF + ' /// Constructeur' + @CRLF + ' /// Aucun paramètre et tous les types sont initialisés à leur' + @CRLF + ' /// valeurs nulles telles que définies dans CommonBase.' + @CRLF + ' ///</summary>' + @CRLF + ' public ' + @TableName + ' ()' + @CRLF + ' {' + @CRLF SELECT @constructor = @constructor + REPLACE( REPLACE(@LigneAffectation , '<ColumnName>', ColumnNameC) , '<ColumnType>', ColumnTypeC) FROM ( SELECT cc.COLUMN_NAME AS ColumnNameC , CASE cc.DATA_TYPE WHEN 'bigint' THEN 'Int_NullValue' WHEN 'binary' THEN 'Int_NullValue' WHEN 'bit' THEN 'Int_NullValue' WHEN 'char' THEN 'String_NullValue' WHEN 'date' THEN 'DateTime_NullValue' WHEN 'datetime' THEN 'DateTime_NullValue' WHEN 'datetime2' THEN 'DateTime_NullValue' WHEN 'datetimeoffset' THEN 'DateTimeOffSet_NullValue' WHEN 'decimal' THEN 'Decimal_NullValue' WHEN 'float' THEN 'Float_NullValue' WHEN 'image' THEN 'ByteTab_NullValue' WHEN 'int' THEN 'Int_NullValue' WHEN 'money' THEN 'Decimal_NullValue' WHEN 'nchar' THEN 'String_NullValue' WHEN 'ntext' THEN 'String_NullValue' WHEN 'numeric' THEN 'Decimal_NullValue' WHEN 'nvarchar' THEN 'String_NullValue' WHEN 'real' THEN 'Double_NullValue' WHEN 'smalldatetime' THEN 'DateTime_NullValue' WHEN 'smallint' THEN 'Int_NullValue' WHEN 'smallmoney' THEN 'Decimal_NullValue' WHEN 'text' THEN 'String_NullValue' WHEN 'time' THEN 'TimeSpan_NullValue' WHEN 'timestamp' THEN 'DateTime_NullValue' WHEN 'tinyint' THEN 'Byte_NullValue' WHEN 'uniqueidentifier' THEN 'Guid_NullValue' WHEN 'varbinary' THEN 'ByteTab_NullValue' WHEN 'varchar' THEN 'String_NullValue' ELSE 'Object' END AS ColumnTypeC , cc.ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS cc WHERE cc.TABLE_NAME = @TableName AND ISNULL(@Schema, cc.TABLE_SCHEMA) = cc.TABLE_SCHEMA ) tc ORDER BY tc.ORDINAL_POSITION SELECT @result = @result + REPLACE( REPLACE(@PrivateProp , '<ColumnName>', ColumnName) , '<ColumnType>', ColumnType) FROM ( SELECT c.COLUMN_NAME AS ColumnName , CASE c.DATA_TYPE WHEN 'bigint' THEN 'Int64' WHEN 'binary' THEN 'Byte[]' WHEN 'bit' THEN 'Boolean' WHEN 'char' THEN 'String' WHEN 'date' THEN 'DateTime' WHEN 'datetime' THEN 'DateTime' WHEN 'datetime2' THEN 'DateTime' WHEN 'datetimeoffset' THEN 'DateTimeOffset' WHEN 'decimal' THEN 'Decimal' WHEN 'float' THEN 'Single' WHEN 'image' THEN 'Byte[]' WHEN 'int' THEN 'Int32' WHEN 'money' THEN 'Decimal' WHEN 'nchar' THEN 'String' WHEN 'ntext' THEN 'String' WHEN 'numeric' THEN 'Decimal' WHEN 'nvarchar' THEN 'String' WHEN 'real' THEN 'Double' WHEN 'smalldatetime' THEN 'DateTime' WHEN 'smallint' THEN 'Int16' WHEN 'smallmoney' THEN 'Decimal' WHEN 'text' THEN 'String' WHEN 'time' THEN 'TimeSpan' WHEN 'timestamp' THEN 'DateTime' WHEN 'tinyint' THEN 'Byte' WHEN 'uniqueidentifier' THEN 'Guid' WHEN 'varbinary' THEN 'Byte[]' WHEN 'varchar' THEN 'String' ELSE 'Object' END AS ColumnType , c.ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS c WHERE c.TABLE_NAME = @TableName AND ISNULL(@Schema, c.TABLE_SCHEMA) = c.TABLE_SCHEMA ) t ORDER BY t.ORDINAL_POSITION SELECT @result = @result + @CRLF + CHAR(9) + ' #endregion Instance Properties' + @CRLF + CHAR(9) + @constructor + @CRLF + CHAR(9) + '}' + @CRLF + CHAR(9) + '}' + @CRLF + @CRLF + '}' --SELECT @result EXEC USP_SaveFile @Result,@Chemin print CAST(@Result AS TEXT)
Maintenant si quelqu'un en a un plus complet pour g�n�rer les classes des couches sup�rieures d�crites dans l'article, �a m'int�resse au plus haut point![]()
Je n'ai rien de tout fait, mais tu peux aussi regarder du cote des templates T4. Ca permet de coder (en C# / VB.NET) la generation de tes classes : Code Generation and T4 Text Templates.
Less Is More
Pensez � utiliser les boutons
,
et les balises code
Desole pour l'absence d'accents, clavier US oblige
Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.
Partager