Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

InsteadOf Triggers with LINQ on Insert

Îåêßíçóå áðü ôï ìÝëïò Χρήστος Γεωργακόπουλος. Τελευταία δημοσίευση από το μέλος azazeal στις 19-11-2008, 22:55. Υπάρχουν 13 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  05-11-2008, 14:43 46000

    InsteadOf Triggers with LINQ on Insert

    Hello to everybody, ψάνω το εξής αλλά δεν βρίσκω λύση:

    Έχω έναν πίνακα με InsteadOf Insert trigger, στον οποίο θέλω να κάνω insert με LINQ. Ο πίνακας έχει primary key με auto value, για το οποίο απ' όσο καταλαβαίνω το LINQ αποτυγχάνει να λάβει νέα τιμή μετά το insert (λόγω του ότι ο trigger κάνει το actual insert), οπότε σκάει στο ξαναφόρτωμα (προσπαθεί να βάλει null value στο primary key).

    Έχει κάποιος υπόψη του κάποιο τρόπο να κάνω το insert με LINQ χωρίς να καταργήσω τον trigger μου;

    Πι Ες: Το μόνο που έχω βρεί είναι αυτό (http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3906744&SiteID=1) που λέει ότι δεν γίνεται, αλλά λέω μήπως...

    Χρήστος Γεωργακόπουλος
    Δημοσίευση στην κατηγορία: , ,
  •  05-11-2008, 15:04 46003 σε απάντηση της 46000

    Απ: InsteadOf Triggers with LINQ on Insert

    Μου φαίνεται ότι και αυτοί οι τύποι ψάχνονται. Μία γρήγορη λύση πάντως θα ήταν να χρησιμοποιήσεις stored procedure για τα insert της συγκεκριμένη κλάσης έτσι ώστε να ελέγξεις εσύ τί γίνεται με το ID.

    Όσον αφορά το SCOPE_IDENTITY() που αναφέρεται, χάσαμεν άπαντες. Το SCOPE_IDENTITY() επιστρέφει την τελευταία τιμή που δημιουργήθηκε μέσα σε ένα συγκεκριμένο batch. Από τη στιγμή που το insert γίνεται από trigger, είναι εκτός scope.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  05-11-2008, 15:09 46004 σε απάντηση της 46003

    Απ: InsteadOf Triggers with LINQ on Insert

    Το SP δεν είναι safe γιατί αφήνει το ενδεχόμενο να έρθει από αλλού το insert στον πίνακα και δεν πρέπει γιατί είναι καθοριστικής σημασίας να διατηρήσει το consistency. Να μην είναι insteadOf το trigger, πάλι δεν παίζει γιατί πρέπει να τροποποιηθούν οι υπάρχουσες εγγραφές πριν γίνει το insert (είναι nested set model).

    Χρήστος Γεωργακόπουλος
  •  05-11-2008, 15:24 46005 σε απάντηση της 46003

    Απ: InsteadOf Triggers with LINQ on Insert

    Θα δοκιμάσω να κάνω extend την Insert του Context για να αναλάβω εγώ το insert...

    Χρήστος Γεωργακόπουλος
  •  05-11-2008, 15:25 46007 σε απάντηση της 46004

    Απ: InsteadOf Triggers with LINQ on Insert

    DevilΠονηρούλη, πόσοι νομίζεις ξέρουν τί είναι το nested set?

    Νομίζω πάντως ότι υπερβάλεις για το sp. Το μόνο που έχει να κάνει είναι ένα απλό insert και να επιστρέψει το @@IDENTITY. Το trigger το διατηρείς ως έχει και θα εκτελεστεί αντί για το INSERT statement που θα βάλεις μέσα στο stored procedure. Απλά, επιστρέφοντας το @@IDENTITY δεν περιορίζεσαι πλέον από το scope και θα επιστρέψεις ό,τι δημιουργήσει το trigger. Είναι κυριολεκτικά το ίδιο με το να κάνεις το insert απευθείας στον πίνακα. Έτσι κι αλλιώς, δίνοντας πρόσβαση στον πίνακα έχεις ήδη δώσει τη μέγιστη δυνατή πρόσβαση σε οποιονδήποτε χρησιμοποιεί την εφαρμογή σου.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  05-11-2008, 15:41 46008 σε απάντηση της 46007

    Απ: InsteadOf Triggers with LINQ on Insert

    SP σαν wrapper για το insert μου το οποίο θα συνεχίσει να παίζει με trigger.... Not bad, θα το δοκιμάσω.

    Χρήστος Γεωργακόπουλος
  •  05-11-2008, 16:20 46014 σε απάντηση της 46007

    Απ: InsteadOf Triggers with LINQ on Insert

    Custom Insert logic with Linq to SQL:

    http://blog.benhall.me.uk/2008/01/custom-insert-logic-with-linq-to-sql.html


    Χρήστος Γεωργακόπουλος
  •  05-11-2008, 21:01 46026 σε απάντηση της 46000

    Απ: InsteadOf Triggers with LINQ on Insert

    Ο trigger κανονικά δεν θα πρέπει να επηρεάζει καθόλου την LINQ (έχω 2-3 projects μέχρις στιγμής που κάνουν heavy trigger use).

    Στον designer της Linq στα πεδία που αλλάζει ο trigger κάνε το Auto Generated Value = true και το Auto-Sync = Always.

    Αν το πρόβλημά σου παραμείνει στείλε μου ένα pm.

  •  05-11-2008, 21:32 46028 σε απάντηση της 46026

    Απ: InsteadOf Triggers with LINQ on Insert

    Το είχα δοκιμάσει αυτό (με Auto sync στο OnInsert, νομίζω το ίδιο κάνει στην περίπτωσή μου). Επισημαίνω ότι είναι insteadOf trigger.

    Anyway, το πρόβλημα λύθυκε με wrapper SP που κάνει το insert, χωρίς ούτε μια γραμή κώδικα στο VS (το Context δέθηκε με την SP για το insert, οπότε κάνει μόνο του extend την default insert). Φαίνεται αρκετά καθαρή λύση.

    Χρήστος Γεωργακόπουλος
  •  06-11-2008, 01:32 46034 σε απάντηση της 46028

    Απ: InsteadOf Triggers with LINQ on Insert

    Αφού σου έπαιξε μην το συζητάς. Απλά μου φαίνεται λίγο μακρύς ο δρόμος για να πάρεις μία auto generated τιμή.

  •  06-11-2008, 01:45 46037 σε απάντηση της 46034

    Απ: InsteadOf Triggers with LINQ on Insert

    azazeal, πρόσεξε τί λέει ο Χρήστος και τί συζητήσαμε ως τώρα. Το LINQ to SQL βρίσκει την τιμή του νέου κλειδιού καλώντας την SCOPE_IDENTITY(). Επειδή όμως η τιμή του νέου κλειδιού δημιουργήθηκε σε ένα trigger και όχι στο sql statement που εκτελεί το LINQ, η SCOPE_IDENTITY() επιστρέφει NULL. Γι αυτό χρειάζεται κάποιος άλλος τρόπος να επιστραφεί η νέα τιμή. Σκοπός δεν είναι απλά να κάνουμε κάτι να παίζει χωρίς να ξέρουμε το γιατί αλλιώς την επόμενη φορά που θα παρουσιαστεί πρόβλημα δεν θα μπορουμε να το αντιμετωπίσουμε. Ίσα-ίσα τώρα μάθαμε και κάτι για το LINQ που μάλλον δεν το είχε φανταστεί κανείς. Γι αυτό και κάνουμε τις συζητήσεις στο forum και όχι μέσω email για να μαθαίνουν όλοι από αυτά που βρίσκουμε.

    Και μια και μιλάμε για LINQ to SQL, που ήσασταν κύριοι στο τελευταίο event το οποίο αφορούσε LINQ, Entity Framework και NHibernate? E?


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  06-11-2008, 02:58 46038 σε απάντηση της 46037

    Απ: InsteadOf Triggers with LINQ on Insert

    Ελπίζω να χρησιμοποιείς Sql Server 2005. Εκεί υπάρχει λύση την οποία και παραθέτω.

     Έστω table Id (int, PK, auto increment, etc), Value nvarchar(400).

    ALTER TRIGGER [tr_Temp_InsteadOfInsert]
    ON [dbo].[Temp]
    INSTEAD OF INSERT
    AS

    BEGIN
       
    SET NOCOUNT ON;

        INSERT INTO Temp
       
    ( [Value] )
       
    OUTPUT inserted.TempId
       
    SELECT
       
    [Value]
       
    FROM INSERTED

    END

    Παναγιώτη Καναβέ: Διάβασα τι έγραψε. Η μαγική λύση είναι στο νέο keyword του Sql Server 2005 "OUTPUT"...

  •  19-11-2008, 19:46 46349 σε απάντηση της 46038

    Απ: InsteadOf Triggers with LINQ on Insert

    Update: Όπως είπε ο Παναγιώτης τελικά δουλεύει μόνο με το scope identity. That means, ότι ούτε με το SP wrapper που έφτιαξα δούλεψε (έκανε το insert αλλά το linq πήρε πίσω σκουπίδια, το κατάλαβα μετά που έφτιαξα ένα πιο σύνθετο unit test). Τελικά η λύση που επέλεξα ήταν να κάνω override το partial insert sub, και εκεί μέσα να παίξω με το χέρι, και βεβαίως μετά να ενημερώσω το instance του linq με τις σωστές τιμές. Δεν είναι απόλυτα κομψό, αλλά δεν είναι και άσχημο.

    @azazeal: Δεν δοκίμασα ακριβώς αυτό που έγραψες, αλλά είμαι σίγουρος ότι θα κάνει το ίδιο πράγμα, γυρνάς κι εσύ την τιμή με output όπως την γύρισα κι εγώ, αλλά το linq την αγνόησε.

    Χρήστος Γεωργακόπουλος
  •  19-11-2008, 22:55 46359 σε απάντηση της 46349

    Απ: InsteadOf Triggers with LINQ on Insert

    Χρήστο,

    α) Χαίρομαι που βρήκες λύση
    β) Λυπάμαι που δεν έδωσες 5 λεπτά να ελέγξεις αυτή που σου πρότεινα γιατί έφαγα αρκετή ώρα μέχρι να το βρώ
    γ) Δες το παρακάτω

    http://msdn.microsoft.com/en-us/library/ms177564.aspx

    "[...] For INSTEAD OF triggers, the returned results are generated as if the INSERT, UPDATE, or DELETE had actually occurred, even if no modifications take place as the result of the trigger operation.[...]"

    Θέλει προσοχή όταν την χρησιμοποιείς αλλά είναι ο μόνος τρόπος μόνο με LINQ να πάρεις αυτό που ζητάς,
     


Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems