<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://www.dotnetzone.gr:443/cs/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>.NET Framework</title><link>https://www.dotnetzone.gr:443/cs/forums/14/ShowForum.aspx</link><description>Θέματα για threading, remoting, reflection, exception handling, security, regex κλπ.</description><dc:language>el</dc:language><generator>CommunityServer 2.1 SP3 (Build: 20423.1)</generator><item><title>Απ: Access DataContext μέσα από το object</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/46855.aspx</link><pubDate>Fri, 12 Dec 2008 02:10:03 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:46855</guid><dc:creator>Χρήστος Γεωργακόπουλος</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/46855.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=46855</wfw:commentRss><description>Παναγιώτη tnx!. θα το μελετήσω και θα σας πω.&lt;br&gt;</description></item><item><title>Απ: Access DataContext μέσα από το object</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/46849.aspx</link><pubDate>Thu, 11 Dec 2008 23:55:07 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:46849</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/46849.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=46849</wfw:commentRss><description>&lt;BLOCKQUOTE&gt;&lt;div&gt;&lt;img src="http://www.dotnetzone.gr/cs/Themes/default/images/icon-quote.gif"&gt; &lt;strong&gt;George J. Capnias:&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;Παναγιώτη τι να σου πω - πήρες πολύ φόρα!!! &lt;img src="http://www.dotnetzone.gr/cs/emoticons/emotion-2.gif" alt="Big Smile" /&gt;&lt;/p&gt;
&lt;p&gt;Σχεδόν με το ένα χέρι πίσω από την πλάτη έκανες τη μισή υλοποίηση του &lt;a target="_blank" href="http://code.google.com/p/subsonicthree/"&gt;Subsonic 3&lt;/a&gt;!!! Αν είναι να ψάχνεστε για "&lt;em&gt;LINQ to SQL&lt;/em&gt;" like ORM που βασίζεται στο Repository pattern και να παίζει με όλες τι βάσεις, τότε είναι έτοιμο - μην το προσπαθείτε από μόνοι σας.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;George J.&lt;br&gt;&lt;/p&gt;&lt;/div&gt;&lt;/BLOCKQUOTE&gt;&lt;br&gt;Μάλλον διαφωνώ. Το Repository είναι pattern και όχι συγκεκριμένη υλοποίηση. Δεν υπάρχει ORM που βασίζεται στο Repository Pattern, το Repository Pattern είναι ένας εύκολος τρόπος να κρύψεις τον κώδικα που αφορά τo ORM από την υπόλοιπη εφαρμογή. Ειδικά το Repository του Subsonic (το οποίο βρίσκεται στο αρχείο&amp;nbsp; Repository.tt) είναι εντελώς βασικό, παρόμοιο με την πρώτη έκδοση της Repository που έγραψα νωρίτερα. Ο χρόνος που χρειάστηκε η πρώτη έκδοση ήταν κάτι λιγότερο από 10 λεπτά. &lt;br&gt;&lt;br&gt;Δεν μπορεί κανείς να πει ότι το Repository είναι έτοιμο όπως δεν μπορεί να πει ότι το Singleton είναι έτοιμο. Υπάρχουν διάφορες υλοποιήσεις με διαφορετικούς συμβιβασμούς η καθεμία. Για παράδειγμα, το τυπικό Singleton για το .NET έχει το θέμα ότι δεν υπάρχει απόλυτως έλεγχος στο πότε δημιουργείται το instance: &lt;br&gt;&lt;br&gt;&lt;span style="color:Black;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;&lt;span style="color:Blue;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;sealed&lt;/span&gt; &lt;span style="color:Blue;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;class&lt;/span&gt; Singleton&lt;br&gt;{&lt;br&gt;    &lt;span style="color:Blue;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; &lt;span style="color:Blue;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;readonly&lt;/span&gt; Singleton instance=&lt;span style="color:Blue;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;new&lt;/span&gt; Singleton();&lt;br&gt;&lt;br&gt;    &lt;span style="color:Green;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;// Explicit static constructor to tell C# compiler&lt;/span&gt;&lt;br&gt;    &lt;span style="color:Green;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;// not to mark type as beforefieldinit&lt;/span&gt;&lt;br&gt;    &lt;span style="color:Blue;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; Singleton()&lt;br&gt;    {&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    Singleton()&lt;br&gt;    {&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span style="color:Blue;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;static&lt;/span&gt; Singleton Instance&lt;br&gt;    {&lt;br&gt;        get&lt;br&gt;        {&lt;br&gt;            &lt;span style="color:Blue;background-color:transparent;font-family:Courier New;font-size:11px;font-weight:normal;"&gt;return&lt;/span&gt; instance;&lt;br&gt;        }&lt;br&gt;    }&lt;br&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;Έτσι και με το Repository. Ένα απλό repository με generics όπως αυτό του Subsonic σε απαλλάσει από το να χειρίζεται contexts μέσα στον κώδικα σου. Τί γίνεται όμως αν θέλεις οι αλλαγές να γίνονται άμεσα? Ή να μαζεύονται στο τέλος? Τί γίνεται με το caching? Ούτε αυτό πρέπει να το ξέρει η υπόλοιπη εφαρμογή σου, οπότε λογικά θα θέλεις να το κρύψεις πίσω από την Get&amp;lt;&amp;gt;. &lt;br&gt;&lt;br&gt;Ο λόγος που έφτιαξα την πιο ευέλικτη μορφή του Repository ήταν ότι ο cgeo είχε ήδη κάνει ερωτήσεις για caching και διαγραφές, οπότε υποψιάζομαι ότι η απλή έκδοση δεν του αρκεί. Άσε που στο thread για &lt;a href="http://www.dotnetzone.gr/cs/forums/thread/46847.aspx"&gt;caching&lt;/a&gt; κουβεντιάζουν για τους διαφορετικούς τρόπους που μπορεί να γίνει το caching αντικειμένων, οπότε μπορώ να θεωρώ ότι μία καρφωτή υλοποίηση ... δεν ικανοποιεί.&lt;br&gt;</description></item><item><title>Απ: Access DataContext μέσα από το object</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/46841.aspx</link><pubDate>Thu, 11 Dec 2008 15:15:50 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:46841</guid><dc:creator>George J. Capnias</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/46841.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=46841</wfw:commentRss><description>&lt;P&gt;Παναγιώτη τι να σου πω - πήρες πολύ φόρα!!! &lt;img src="http://www.dotnetzone.gr/cs/emoticons/emotion-2.gif" alt="Big Smile" /&gt;&lt;/P&gt;
&lt;P&gt;Σχεδόν με το ένα χέρι πίσω από την πλάτη έκανες τη μισή υλοποίηση του &lt;A target=_blank href="http://code.google.com/p/subsonicthree/"&gt;Subsonic 3&lt;/A&gt;!!! Αν είναι να ψάχνεστε για "&lt;EM&gt;LINQ to SQL&lt;/EM&gt;" like ORM που βασίζεται στο Repository pattern και να παίζει με όλες τι βάσεις, τότε είναι έτοιμο - μην το προσπαθείτε από μόνοι σας.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;George J.&lt;BR&gt;&lt;/P&gt;</description></item><item><title>Απ: Access DataContext μέσα από το object</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/46839.aspx</link><pubDate>Thu, 11 Dec 2008 09:42:52 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:46839</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/46839.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=46839</wfw:commentRss><description>&lt;P&gt;&lt;BLOCKQUOTE&gt;&lt;div&gt;&lt;img src="http://www.dotnetzone.gr/cs/Themes/default/images/icon-quote.gif"&gt; &lt;strong&gt;Χρήστος Γεωργακόπουλος:&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;BR&gt;Θα ψάξω να βρω κάποια διαφορετική υλοποίηση, το πραγματικό μου πρόβλημα πάντως είναι το εξής:&amp;nbsp; Έχω ένα Order που έχει πολλά OrderItems. Θέλω να κάνω raise ένα event στα OrderItems, έτσι ώστε όταν αλλάζει το quantity τους, να πιάνει το event το Order και να ξαναυπολογίζει το μεταφορικό κόστος (που βεβαίως είναι πεδίο πάνω στο Order). Το πρόβλημα είναι ότι όταν καταλάβει το Order ότι άλλαξε το quantity από ένα OrderItem, δεν μπορεί να βρει το context που βρίσκεται για να κάνει τις δουλιές που χρειάζεται.&lt;BR&gt;&lt;BR&gt;&lt;/div&gt;&lt;/BLOCKQUOTE&gt;&lt;/P&gt;
&lt;P&gt;Γιατί να μην κάνεις το πιο απλό, να καλείς μία CalculateCost επάνω στο Order για να υπολογίσει το κόστος πριν αποθηκεύσεις τις αλλαγές? Αν τα OrderItems είναι ήδη στη μνήμη το κόστος θα είναι μικρό. Αλλά και αν δεν θέλεις να το κάνεις αυτό κάθε φορά, οι αλλαγές στα OrderItems γίνονται από δικό σου κώδικα, οπότε μπορείς να καλέσεις την CalculateCost στο τέλος του. Επιπλέον, εκτός και αν έχεις αλλάξει με το χέρι τα Associations στο LINQ to SQL, η κλάση OrderItem πρέπει να περιέχει και ένα property Order το οποίο παραπέμπει στο parent order. Μπορείς όταν τροποποιείς τα OrderItems να τα βάλεις είτε να καλέσουν την CalculateCost ή να θέσουν ένα flag το οποίο θα ελέγξεις αργότερα για να δεις αν χρειάζεται να κάνεις CalculateCost πριν σώσεις.&lt;/P&gt;
&lt;P&gt;Υπάρχουν πολύ ευκολότεροι τρόποι να κάνεις αυτό που θέλεις από το να παλεύεις με Reflection να βρεις ποιό είναι το parent Order (που τον έχεις ήδη) και μετά και μετά και μετά. Η χρήση ενός επιπλέον layer θα διευκολύνει πολύ τα πράγματα και θα μειώσει τον όγκο δουλειάς - εξάλλου ήδη έχεις ξοδέψει περισσότερο χρόνο ψάχνοντας απ' όσο θα χρειαζόταν για να φτιάξεις το επιπλέον layer. &lt;BR&gt;Όταν έχεις μία συγκεκριμένη μέθοδο SaveCustomer έχεις και ένα συγκεκριμένο σημείο να κάνεις validations, recalculations και ότι άλλο θέλεις. Διαφορετικά θα πρέπει να σπείρεις μία απλή διαδικασία σε πολλές διαφορετικές κλάσεις. Η πολυπλοκότητα θα είναι τόσο μεγάλη που σύντομα δεν θα ξέρεις ποιά αλλαγή προκαλεί ποιό calculation.&lt;/P&gt;</description></item><item><title>Απ: Access DataContext μέσα από το object</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/46838.aspx</link><pubDate>Thu, 11 Dec 2008 09:29:22 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:46838</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/46838.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=46838</wfw:commentRss><description>&lt;P&gt;Ο Γιώργος έχει δίκιο. Τα αντικείμενα υπάρχουν ανεξάρτητα από το όποιο DataContext χρησιμοποιείται για να τα διαβάσεις ή να τα αποθηκεύσει, έτσι δεν υπάρχει τρόπος το αντικείμενο να ξέρει από ποιό DataContext δημιουργήθηκε ή σε ποιό είναι attach κάθε στιγμή - πολύ απλά, μπορεί να μην είναι attached πουθενά. Μία καλή αναλογία είναι να σκεφτείς το DataContext ως ένα Connection και τα αντικείμενα ως τα Datasets, Datatables που μπορεί να περάσουν από αυτή. Ένα DataTable δεν ξέρει ποτέ ποιό connection το δημιούργησε ή ποιό θα το αποθηκεύσει στο μέλλον.&lt;/P&gt;
&lt;P&gt;Αυτό είναι ένα Καλό Πράγμα. Έτσι δεν είσαι υποχρεωμένος να κρατάς το ίδιο DataContext συνέχεια στη μνήμη και να κάνεις track αλλαγές οι οποίες μπορεί ποτέ να μην καταλήξουν στη βάση. Μπορείς άνετα να δημιουργείς ένα DataContext αντικείμενο μόνο όταν θέλεις να διαβάσεις από τη βάση ή να αποθηκεύσεις τις αλλαγές σου σε αυτή.&lt;/P&gt;
&lt;P&gt;Θα μου πεις τώρα, και ήδη το είπες, "Δηλαδή θα πρέπει να πλημμυρίσει ο κώδικας μου με DataContexts και DeleteOnSubmit ? Εδώ είπαμε να ξεχωρίσουμε αντικείμενα από το Data Layer και εσύ μου λες, να τα ξαναμπλέξουμε ξανά ?" . Προφανώς και δεν είναι καθόλου καλή ιδέα να τα μπλέξουμε ξανά. Ευτυχώς το πρόβλημα (και η λύση του) είναι κλασσικό για τα ORMs και έχει αντιμετωπιστεί εδώ και καιρό. &lt;/P&gt;
&lt;P&gt;Η λύση λέγεται Repository Pattern και ουσιαστικά είναι μία κλάση η οποία στην απλούστερη περίπτωση κρύβει από εσένα το DataContext και τις λεπτομέρειες του και σου δίνει ένα καθαρό interface με εντολές GetByID, Delete, Update. To Repository από πίσω αναλαμβάνει να χειριστεί το ή τα DataContext που χρειάζονται. Οι πιο προχωρημένες υλοποιήσεις διαχειρίζονται τα DataContexts και τα Transactions έτσι ώστε να υλοποιήσουν long running transactions, caching, concurrency και session management. &lt;/P&gt;
&lt;P&gt;Κατά κανόνα μία κλάση Repository υλοποιεί κάτι σαν το παρακάτω interface:&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;interface&lt;/SPAN&gt; IRepository&amp;lt;T&amp;gt;&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; T GetByID(&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;int&lt;/SPAN&gt; id);&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;void&lt;/SPAN&gt; Save(T entity);&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;void&lt;/SPAN&gt; Delete(T entity);&lt;BR&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Μία απλή υλοποίηση μπορεί να είναι η παρακάτω:&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;class&lt;/SPAN&gt; CustomerRepository:IRepository&amp;lt;Customer&amp;gt;&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;#region&lt;/SPAN&gt; IRepository&amp;lt;Customer&amp;gt; Members&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; Customer GetByID(&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;int&lt;/SPAN&gt; id)&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (MyDataContext ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt; MyDataContext())&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;return&lt;/SPAN&gt; ctx.Customers.SingleOrDefault(c =&amp;gt; c.CustomerID == id);&lt;BR&gt;}&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;void&lt;/SPAN&gt; Save(Customer entity)&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (MyDataContext ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt; MyDataContext())&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;if&lt;/SPAN&gt; (entity.CustomerID &amp;gt; 0)&lt;BR&gt;ctx.Customers.Attach(entity);&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;else&lt;/SPAN&gt;&lt;BR&gt;ctx.Customers.InsertOnSubmit(entity);&lt;BR&gt;ctx.SubmitChanges();&lt;BR&gt;}&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;void&lt;/SPAN&gt; Delete(Customer entity)&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (MyDataContext ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt; MyDataContext())&lt;BR&gt;{&lt;BR&gt;&lt;BR&gt;ctx.Customers.DeleteOnSubmit(entity);&lt;BR&gt;ctx.SubmitChanges();&lt;BR&gt;}&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;#endregion&lt;/SPAN&gt;&lt;BR&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Έτσι μπορείς να γράψεις π.χ. τον παρακάτω κώδικα:&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;CustomerRepository repository &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt; CustomerRepository();&lt;BR&gt;Customer customer=repository.GetByID(35);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Η κλάση CustomerRepository δεν είναι και ότι καλύτερο. Είμαι σίγουρος ότι κανείς δεν έχει όρεξη να γράφει ένα Repository για κάθε κλάση. Για να φτιαχτεί μία γενική κλάση repository χρειάζονται δύο πράγματα: να έχουμε πρόσβαση στην ctx.Customers χωρίς να την προσδιορίσουμε και κάπως, να απαλλαγούμε από την αναφορά στο CustomerID.&lt;/P&gt;
&lt;P&gt;Η πρώτη αλλαγή είναι σχετικά εύκολη, καθώς η Customers είναι χονδρικά μία συντόμευση για την GetTable&amp;lt;Customer&amp;gt;. Η δεύτερη αλλαγή γίνεται επίσης εύκολα αν θυμηθούμε ότι μπορούμε να περάσουμε το c =&amp;gt; c.CustomerID == id ως παράμετρ. Μπορούμε λοιπόν αντί για την GetByID να φτιάξουμε μία γενική Get:&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; T Get(Func&amp;lt;T,&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;bool&lt;/SPAN&gt;&amp;gt; criteria) &lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (MyDataContext ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt; MyDataContext())&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;return&lt;/SPAN&gt; ctx.GetTable&amp;lt;T&amp;gt;().SingleOrDefault(criteria);&lt;BR&gt;}&lt;BR&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Και η κλήση γίνεται:&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;Repository&amp;lt;Customer&amp;gt; repository &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt; Repository&amp;lt;Customer&amp;gt;();&lt;BR&gt;Customer customer &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; repository.Get(c =&amp;gt; c.CustomerID == 35);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Μας μένει όμως το MyDataContext. Μπορούμε να το ξεφορτωθούμε και αυτό αν αλλάξουμε τον ορισμό της Repository σε&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;class&lt;/SPAN&gt; Repository&amp;lt;T, C&amp;gt; &lt;BR&gt;where T:&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;class&lt;/SPAN&gt;&lt;BR&gt;where C:DataContext&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Έτσι η Get γίνεται:&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; T Get(Func&amp;lt;T,&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;bool&lt;/SPAN&gt;&amp;gt; criteria) &lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (MyDataContext ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt; MyDataContext())&lt;BR&gt;{&lt;BR&gt;Table&amp;lt;T&amp;gt; table &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; ctx.GetTable&amp;lt;T&amp;gt;();&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;return&lt;/SPAN&gt; table.SingleOrDefault(criteria);&lt;BR&gt;}&lt;BR&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Η Save έχει ακόμα ένα προβληματάκι, καθώς ελέγχει το CustomerID για να δει αν ένα αντικείμενο είναι νέο και θέλει Insert, ή προϋπήρχε και θέλει Attach. Θα μπορούσα να ψάξω και να βρω ποιά πεδία είναι τα Primary keys του πίνακα αλλά δεν μου αρέσει. Αντί γι αυτό, θα περάσω και αυτό το κριτήριο ως παράμετρο. Έτσι η Repository γίνεται: &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;class&lt;/SPAN&gt; Repository&amp;lt;T, C&amp;gt; &lt;BR&gt;where T:&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;class&lt;/SPAN&gt;&lt;BR&gt;where C:DataContext, &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt;()&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;protected&lt;/SPAN&gt; Func&amp;lt;T, &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;bool&lt;/SPAN&gt;&amp;gt; IsNew;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; Repository(Func&amp;lt;T, &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;bool&lt;/SPAN&gt;&amp;gt; isNewCriteria)&lt;BR&gt;{&lt;BR&gt;IsNew &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; isNewCriteria;&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;#region&lt;/SPAN&gt; IRepository&amp;lt;Customer&amp;gt; Members&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; T Get(Func&amp;lt;T,&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;bool&lt;/SPAN&gt;&amp;gt; criteria) &lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (C ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt; C())&lt;BR&gt;{&lt;BR&gt;Table&amp;lt;T&amp;gt; table &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; ctx.GetTable&amp;lt;T&amp;gt;();&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;return&lt;/SPAN&gt; table.SingleOrDefault(criteria);&lt;BR&gt;}&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;void&lt;/SPAN&gt; Save(T entity)&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (C ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt; C())&lt;BR&gt;{&lt;BR&gt;Table&amp;lt;T&amp;gt; table &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; ctx.GetTable&amp;lt;T&amp;gt;();&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;if&lt;/SPAN&gt; (IsNew(entity))&lt;BR&gt;table.Attach(entity);&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;else&lt;/SPAN&gt;&lt;BR&gt;table.InsertOnSubmit(entity);&lt;BR&gt;ctx.SubmitChanges();&lt;BR&gt;}&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;void&lt;/SPAN&gt; Delete(T entity)&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (C ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt; C())&lt;BR&gt;{&lt;BR&gt;Table&amp;lt;T&amp;gt; table &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; ctx.GetTable&amp;lt;T&amp;gt;();&lt;BR&gt;table.DeleteOnSubmit(entity);&lt;BR&gt;ctx.SubmitChanges();&lt;BR&gt;}&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;#endregion&lt;/SPAN&gt;&lt;BR&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Το κριτήριο για το αν ένα αντικείμενο είναι νέο το ονομάζω IsNew και το περνάω στον constructor της Repository&lt;/P&gt;
&lt;P&gt;Τώρα, η κλήση της Get γίνεται:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;Repository&amp;lt;Customer,MyDataContext&amp;gt; repository &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt; Repository&amp;lt;Customer,MyDataContext&amp;gt;(c=&amp;gt; c.CustomerID&amp;gt;0);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Customer customer &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; repository.Get(c =&amp;gt; c.CustomerID == 35);&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Αλλά πάλι, αυτός ο constructor δεν μου αρέσει. Γι αυτό θα φτιάξω μία νέα CustomerRepository ως εξής:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class CustomerRepository : Repository&amp;lt;Customer,MyDataContext&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public CustomerRepository()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsNew = (c =&amp;gt; c.CustomerID &amp;gt; 0);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;και θα βγάλω τον Constructor από την Repository&amp;lt;&amp;gt;. Τώρα η κλήση μου γίνεται :&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CustomerRepository repository = new CustomerRepository();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Customer customer = repository.Get(c =&amp;gt; c.CustomerID == 35);&lt;/P&gt;
&lt;P&gt;Θα μπορούσα να προσθέσω κι άλλα πράγματα. Θα μπορούσα να κάνω το ίδιο κόλπο με την IsNew και να περνάω και το κριτήριο της Get ως παράμετρο στον constructor. Θα μπορούσα να προσθέσω και κάποιες Where, First κλπ, για να κάνω αναζητήσης όπως έχω συνηθίσει με το LINQ. Αντί γι αυτό όμως θέλω να περάσω στα πιο προχωρημένα θέματα.&lt;/P&gt;
&lt;P&gt;Αυτή τη στιγμή χρησιμοποιώ ντε και καλά ένα μόνο context τη φορά. Αυτό με βολεύει αν θέλω οι αλλαγές μου να περνάνε απευθείας στη βάση, μπορεί όμως να θέλω να υλοποιήσω διαφορετική λογική. Για παράδειγμα, μπορεί να θέλω να μαζέψω όλες τις αλλαγές που θέλω να κάνω σε ένα σύνολο αντικειμένων και να τις αποθηκεύσω όλες μαζί στο τέλος. Για να το κάνω αυτό, πρέπει το DataContext μου να παραμένει στη μνήμη, και μάλιστα να είναι διαθέσιμο για χρήση μεταξύ πολλών Repositories. Χρειάζομαι ένα τρόπο να λέω στην Repository που να βρει και πως να χρησιμοποιήσει το DataContext.&lt;/P&gt;
&lt;P&gt;Για να το πετύχω αυτό, θα φτιάξω διάφορες κλάσεις ContextPolicy. Άλλη θα μου επιστρέφει ένα διαφορετικό context κάθε φορά και άλλη θα μου επιστρέφει το ίδιο κάθε φορά. Επειδή όμως δεν θέλω να χάσω και την ευκολία του using, τα Factories δεν θα επιστρέφουν ένα DataContext αλλά ένα ContextWrapper:&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;class&lt;/SPAN&gt; ContextWrapper&amp;lt;C&amp;gt; : IDisposable where C : DataContext&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; C Context { get; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;protected&lt;/SPAN&gt; set; }&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; ContextWrapper(C context)&lt;BR&gt;{&lt;BR&gt;Context &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; context;&lt;BR&gt;}&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;#region&lt;/SPAN&gt; IDisposable Members&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;void&lt;/SPAN&gt; Dispose()&lt;BR&gt;{&lt;BR&gt;Context.Dispose();&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;#endregion&lt;/SPAN&gt;&lt;BR&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Τα policies θα υλοποιούν το IContextPolicy interface&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;interface&lt;/SPAN&gt; IContextPolicy&amp;lt;C&amp;gt; where C : DataContext&lt;BR&gt;{&lt;BR&gt;ContextWrapper&amp;lt;C&amp;gt; Get();&lt;BR&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Η κλάση ContextWrapper είναι η παρακάτω: &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class ContextWrapper&amp;lt;C&amp;gt; : IDisposable where C : DataContext&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public C Context { get; protected set; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ContextWrapper(C context)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Context = context;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public virtual void Dispose()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;H Dispose είναι επίτηδες κενή, γιατί θα χρησιμοποιήσω μία άλλη κλάση, την DisposingContextWrapper για τις περιπτώσεις που θέλω να κλείνω το context κάθε φορά&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class DisposingContextWrapper&amp;lt;C&amp;gt; : ContextWrapper&amp;lt;C&amp;gt; where C : DataContext&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public DisposingContextWrapper(C context)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : base(context)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {}&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region IDisposable Members&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void Dispose()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Context.Dispose();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;Και τώρα, μπορώ να φτιάξω μία ContextPolicy η οποία χρησιμοποιεί πάντα το ίδιο context:&lt;BR&gt;&amp;nbsp;public class SingleContextPolicy&amp;lt;C&amp;gt; : IContextPolicy&amp;lt;C&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; where C : DataContext, new()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; C context;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region IContextPolicy&amp;lt;C&amp;gt; Members&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ContextWrapper&amp;lt;C&amp;gt; Get()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (context==null)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context = new C();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new ContextWrapper&amp;lt;C&amp;gt;(context);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;Ή μία ContextFactory η οποία πάντα δημιουργεί ένα νέο context:&lt;BR&gt;public class MultipleContextPolicy&amp;lt;C&amp;gt; : IContextPolicy&amp;lt;C&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; where C : DataContext, new()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region IContextPolicy&amp;lt;C&amp;gt; Members&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ContextWrapper&amp;lt;C&amp;gt; Get()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; C context = new C();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return new DisposingContextWrapper&amp;lt;C&amp;gt;(context);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;Οι αλλαγές που θα κάνω στην Repository είναι ελάχιστες&lt;BR&gt;class Repository&amp;lt;T, C&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where T:class&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where C:DataContext, new()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected IContextPolicy&amp;lt;C&amp;gt; _contextPolicy;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected Func&amp;lt;T, bool&amp;gt; IsNew;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region IRepository&amp;lt;Customer&amp;gt; Members&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public T Get(Func&amp;lt;T,bool&amp;gt; criteria) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (ContextWrapper&amp;lt;C&amp;gt; ctx = _contextPolicy.Get())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Table&amp;lt;T&amp;gt; table = ctx.Context.GetTable&amp;lt;T&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return table.SingleOrDefault(criteria);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Save(T entity)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (ContextWrapper&amp;lt;C&amp;gt; ctx = _contextPolicy.Get())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Table&amp;lt;T&amp;gt; table = ctx.Context.GetTable&amp;lt;T&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (IsNew(entity))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; table.Attach(entity);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; table.InsertOnSubmit(entity);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctx.Context.SubmitChanges();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Delete(T entity)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (ContextWrapper&amp;lt;C&amp;gt; ctx = _contextPolicy.Get())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Table&amp;lt;T&amp;gt; table = ctx.Context.GetTable&amp;lt;T&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; table.DeleteOnSubmit(entity);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctx.Context.SubmitChanges();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;Απλά, αντί για να φτιάχνω τα context με το χέρι, καλώ την Get του Context Factory.&lt;/P&gt;
&lt;P&gt;Μπορώ τώρα να ορίσω ότι η CustomerRepository θα χρησιμοποιεί πάντα ένα context:&lt;BR&gt;class CustomerRepository : Repository&amp;lt;Customer,MyDataContext&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public CustomerRepository()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsNew = (c =&amp;gt; c.CustomerID &amp;gt; 0);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _contextPolicy = new SingleContextPolicy&amp;lt;MyDataContext&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;Επόμενο βήμα τώρα. Αφού μπορώ να έχω ένα κοινό context, γιατί να μην μπορώ να μαζέψω όλες τις αλλαγές μέχρι τη στιγμή που θέλω εγώ? Και χωρίς φυσικά να κάνω hard-code αυτή τη συμπεριφορά? Η απάντηση είναι άλλο ένα σετ από Policies, τα Submission policies. Θα προσθέσω επίσης μία SaveAll στη Repository η οποία θα καλεί απευθείας την SubmitChanges. Τα Submission policies είναι τα εξής&lt;BR&gt;interface ISubmissionPolicy&amp;lt;C&amp;gt; where C : DataContext&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void Submit(C context);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class AutoSubmitPolicy&amp;lt;C&amp;gt;:ISubmissionPolicy&amp;lt;C&amp;gt; where C : DataContext&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region ISubmissionPolicy&amp;lt;C&amp;gt; Members&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Submit(C context)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.SubmitChanges();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class DeferSubmitPolicy&amp;lt;C&amp;gt; : ISubmissionPolicy&amp;lt;C&amp;gt; where C : DataContext&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region ISubmissionPolicy&amp;lt;C&amp;gt; Members&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Submit(C context)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {}&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;Και η repository γίνεται&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;class&lt;/SPAN&gt; Repository&amp;lt;T, C&amp;gt; &lt;BR&gt;where T:&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;class&lt;/SPAN&gt;&lt;BR&gt;where C:DataContext, &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;new&lt;/SPAN&gt;()&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;protected&lt;/SPAN&gt; IContextPolicy&amp;lt;C&amp;gt; _contextPolicy;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;protected&lt;/SPAN&gt; ISubmissionPolicy&amp;lt;C&amp;gt; _submissionPolicy;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;protected&lt;/SPAN&gt; Func&amp;lt;T, &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;bool&lt;/SPAN&gt;&amp;gt; IsNew;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;#region&lt;/SPAN&gt; IRepository&amp;lt;Customer&amp;gt; Members&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; T Get(Func&amp;lt;T,&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;bool&lt;/SPAN&gt;&amp;gt; criteria) &lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (ContextWrapper&amp;lt;C&amp;gt; ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; _contextPolicy.Get())&lt;BR&gt;{&lt;BR&gt;Table&amp;lt;T&amp;gt; table &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; ctx.Context.GetTable&amp;lt;T&amp;gt;();&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;return&lt;/SPAN&gt; table.SingleOrDefault(criteria);&lt;BR&gt;}&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;void&lt;/SPAN&gt; Save(T entity)&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (ContextWrapper&amp;lt;C&amp;gt; ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; _contextPolicy.Get())&lt;BR&gt;{&lt;BR&gt;Table&amp;lt;T&amp;gt; table &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; ctx.Context.GetTable&amp;lt;T&amp;gt;();&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;if&lt;/SPAN&gt; (IsNew(entity))&lt;BR&gt;table.Attach(entity);&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;else&lt;/SPAN&gt;&lt;BR&gt;table.InsertOnSubmit(entity);&lt;BR&gt;&lt;BR&gt;_submissionPolicy.Submit(ctx.Context);&lt;BR&gt;}&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;void&lt;/SPAN&gt; SaveAll()&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (ContextWrapper&amp;lt;C&amp;gt; ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; _contextPolicy.Get())&lt;BR&gt;{&lt;BR&gt;ctx.Context.SubmitChanges();&lt;BR&gt;}&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;void&lt;/SPAN&gt; Delete(T entity)&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;using&lt;/SPAN&gt; (ContextWrapper&amp;lt;C&amp;gt; ctx &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; _contextPolicy.Get())&lt;BR&gt;{&lt;BR&gt;Table&amp;lt;T&amp;gt; table &lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:red;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;=&lt;/SPAN&gt; ctx.Context.GetTable&amp;lt;T&amp;gt;();&lt;BR&gt;table.DeleteOnSubmit(entity);&lt;BR&gt;_submissionPolicy.Submit(ctx.Context);&lt;BR&gt;}&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:blue;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;#endregion&lt;/SPAN&gt;&lt;BR&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="BACKGROUND-COLOR:transparent;FONT-FAMILY:Courier New;COLOR:black;FONT-SIZE:11px;FONT-WEIGHT:normal;"&gt;&lt;/SPAN&gt;Και μπορώ πλέον να ορίσω ένα CustomerRepository ως εξής:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; class CustomerRepository : Repository&amp;lt;Customer,MyDataContext&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public CustomerRepository()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IsNew = (c =&amp;gt; c.CustomerID &amp;gt; 0);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _contextPolicy = new SingleContextPolicy&amp;lt;MyDataContext&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _submissionPolicy = new DeferSubmitPolicy&amp;lt;MyDataContext&amp;gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;Αν μάλιστα προσθέσω και ένα constructor στην Repository ο οποίος θα δέχεται τα policies ως παραμέτρους, μπορώ να ορίσω Repositories με διαφορετική συμπεριφορά σε διαφορετικά σημεία του κώδικα, για την ίδια πάντα κλάση.&lt;/P&gt;
&lt;P&gt;Με αντίστοιχο τρόπο μπορώ να συνεχίσω για να προσθέσω concurrency, transactions, caching και ότι άλλο μπορώ να φανταστώ. Μάλιστα, μπορώ να πάω άλλο ένα βήμα παραπέρα και να χρησιμοποιήσω κάποιο dependency inversion μηχανισμό όπως το Unity, το Spring.Net ή κάποιο δικής μου κατασκευής για να ορίζω ποιά policies θα χρησιμοποιούνται μέσω configuration.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;ΥΓ. Για να μην αναρωτιέται που πήγα και κατέβασα αυτές τις ιδέες, απλά αντέγραψα από ... το NHibernate. Η ιδέα των policies προέρχεται από τη C++ και τα templates και εμφανίζεται και στην C# με διάφορες παραλλαγές όπως providers, factories κλπ. Μία αναζήτηση για LINQ to SQL Repository θα επιστρέψει αρκετές υλοποιήσεις.&lt;/P&gt;</description></item><item><title>Απ: Access DataContext μέσα από το object</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/46837.aspx</link><pubDate>Thu, 11 Dec 2008 08:00:26 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:46837</guid><dc:creator>Χρήστος Γεωργακόπουλος</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/46837.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=46837</wfw:commentRss><description>Sorry για το τρίτο απανωτό, αλλά έχω χωθεί στο reflector και ψάχνω....&lt;br&gt;&lt;br&gt;Λοιπόν, τα objects μπορεί να είναι... objects, αλλά τα EntityRefs που έχουν πάνω τους (οι δεσμοί με άλλα αντικείμενα) δεν είναι τόσο χαζά. Το EntityRef κρύβει μέσα του ένα member με το όνομα Source το οποίο είναι IEnumerable. Δεν το έψαξα πιο πολύ, αλλά υποθέτω στο runtime ως source του EntityRef, ορίζεται το Table του Context. Γι' αυτό όταν έχω ένα αντικείμενο με πεθαμένο context και προσπαθήσω να φορτώσω ένα referenced object, χτυπάει και ξέρει ότι το context του έχει πεθάνει. Η αν το πάρουμε ανάποδα, το EntityRef έχει απόλυτη γνώση του context στο οποίο ανήκει το αντικείμενό μου, για να ξέρει πως να φορτώσει referenced objects.&lt;br&gt;&lt;br&gt;Άρα... ζηλεύω. Τα EntityRefs έχουν μέσα την πληροφορία που θέλω (το context εν τέλει) αλλά το κρατάνε private. Πρέπει να βρω κάποιο τρόπο να το βγάλω έξω... Θέλω κι εγώ!!!&lt;br&gt;</description></item><item><title>Απ: Access DataContext μέσα από το object</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/46836.aspx</link><pubDate>Thu, 11 Dec 2008 07:26:12 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:46836</guid><dc:creator>Χρήστος Γεωργακόπουλος</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/46836.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=46836</wfw:commentRss><description>Ο Γιώργος έχει δίκιο, τα objects είναι... εντελώς objects, απλά κάνουν implement ένα interface. Δεν έχουν την παραμικρή ιδέα για το τι γίνεται γύρω τους. Αυτοί που έχουν μια σχετική δύναμη είναι τα tables σου δίνει το context. Από εκεί γίνονται όλες οι δουλιές που έχουν να κάνουν με το context. Αλλά δεν διευκολύνουν κάτι, για να έχεις πρόσβαση στα tables πρέπει να ξέρεις το context...&lt;br&gt;&lt;br&gt;Θα ψάξω να βρω κάποια διαφορετική υλοποίηση, το πραγματικό μου πρόβλημα πάντως είναι το εξής:&amp;nbsp; Έχω ένα Order που έχει πολλά OrderItems. Θέλω να κάνω raise ένα event στα OrderItems, έτσι ώστε όταν αλλάζει το quantity τους, να πιάνει το event το Order και να ξαναυπολογίζει το μεταφορικό κόστος (που βεβαίως είναι πεδίο πάνω στο Order). Το πρόβλημα είναι ότι όταν καταλάβει το Order ότι άλλαξε το quantity από ένα OrderItem, δεν μπορεί να βρει το context που βρίσκεται για να κάνει τις δουλιές που χρειάζεται.&lt;br&gt;&lt;br&gt;Το επιπλέον layer που ανέφερε ο Γιώργος πάντως δεν με ενθουσιάζει από άποψη όγκου δουλιάς, θα δω τι μπορώ να κολήσω πάνω στα objects μου για να κάνω τη δουλιά που θέλω...&lt;br&gt;&lt;br&gt;</description></item><item><title>Απ: Access DataContext μέσα από το object</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/46835.aspx</link><pubDate>Thu, 11 Dec 2008 05:18:55 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:46835</guid><dc:creator>Χρήστος Γεωργακόπουλος</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/46835.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=46835</wfw:commentRss><description>&lt;BLOCKQUOTE&gt;&lt;div&gt;&lt;img src="http://www.dotnetzone.gr/cs/Themes/default/images/icon-quote.gif"&gt; &lt;strong&gt;Markos:&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;Όσον αφορά το Linq ακόμη ψάχνομαι. Ίσως, όμως, αυτά τα δύο άρθρα σου φανούν χρήσιμα (&lt;a href="http://www.west-wind.com/WebLog/posts/160237.aspx"&gt;1&lt;/a&gt;, &lt;a href="http://www.codeproject.com/KB/linq/LINQToSQLBaseCRUDClass.aspx"&gt;2&lt;/a&gt;).&lt;/p&gt;&lt;/div&gt;&lt;/BLOCKQUOTE&gt;&lt;br&gt;&lt;br&gt;Tnx. Το άρθρο του Strahl το είχα δεί, δεν έχω καταλάβει εντελώς τι κάνει (δεν το έχω δει τόσο προσεκτικά) αλλά από τον κώδικά του δεν νομίζω ότι μου δίνει κάποια λύση. Το δεύτερο στο CodeProject είναι ψευτολύση, γιατί τα methods που προσθέτει ανοίγουν δικό τους instance του context για να κάνουν τη δουλιά, και δεν χρησιμοποιούν το υπάρχον (+ το χειρότερο, φωνάζουν μόνα τους submitChanges), είναι νομίζω τελείως εκτός best practices.&lt;br&gt;</description></item><item><title>Απ: Access DataContext μέσα από το object</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/46822.aspx</link><pubDate>Wed, 10 Dec 2008 20:45:43 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:46822</guid><dc:creator>Markos</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/46822.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=46822</wfw:commentRss><description>&lt;P&gt;Όσον αφορά το Linq ακόμη ψάχνομαι. Ίσως, όμως, αυτά τα δύο άρθρα σου φανούν χρήσιμα (&lt;A href="http://www.west-wind.com/WebLog/posts/160237.aspx"&gt;1&lt;/A&gt;, &lt;A href="http://www.codeproject.com/KB/linq/LINQToSQLBaseCRUDClass.aspx"&gt;2&lt;/A&gt;).&lt;/P&gt;</description></item><item><title>Απ: Access DataContext μέσα από το object</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/46817.aspx</link><pubDate>Wed, 10 Dec 2008 16:27:36 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:46817</guid><dc:creator>George J. Capnias</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/46817.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=46817</wfw:commentRss><description>&lt;P&gt;Ιδέα δεν νομίζω ότι υπάρχει, μιας και ο σκοπός είναι αυτός:&amp;nbsp;το object να μην έχει context, εκτός αν εσύ του το καθορίσεις. Μπορείς να κάνεις extensions στο object σου για να σε βοηθήσουν να τα χειρίζεσαι πιο εύκολα, όπως την delete που έχεις φτιάξει ήδη, αλλά η αλήθεια είναι ότι χρειάζεσαι ένα layer επάνω από αυτό που είσαι - data layer - για να μπορέσεις να υλοποιήσεις κάτι τέτοιο.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;George J.&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>Access DataContext μέσα από το object</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/46808.aspx</link><pubDate>Tue, 09 Dec 2008 22:43:57 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:46808</guid><dc:creator>Χρήστος Γεωργακόπουλος</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/46808.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=14&amp;PostID=46808</wfw:commentRss><description>Hello, έχω ένα objectάκι που μου έχει φτιάξει το linq, πχ Customer. Θέλω να του βάλω ένα method Delete, έτσι ώστε να καλώ το MyCustomer.Delete και να μαρκάρεται για delete μέσα στο context.&lt;br&gt;Αυτό για να γίνει εξωτερικά, θα έπρεπε να δώσω MyContext.DeleteOnSubmit(MyCustomer). Και ερωτώ: Μέσα απο το Customer, πως μπορώ να πάρω το context που το managάρει;&lt;br&gt;Αυτή τη στιγμή περνάω το context σαν παράμετρο (Public Sub Delete(context as DbContext)) αλλά μου κάνει σε παράλογο να μην έχει το Customer reference στο Context που το χειρίζεται και να αναγκάζομαι να του το ξαναδώσω.&lt;br&gt;&lt;br&gt;Έχει κανείς κάποια ιδέα;&lt;br&gt;</description></item></channel></rss>