DLINQ: Egyszerű tárolt eljárások esete az MSDN-nel

Egyszerűnek tekinthetjük az alábbi, elég tipikusnak mondható tárolt eljárást, ami visszaadja egy adott tábla rekordjainak számát:

    CREATE PROCEDURE dbo.GetCustomerCount
    AS
        SELECT Count(*) FROM Customers

Amikor megpróbáljuk meghívni, ugyanúgy járunk el, mint máskor, rádobjuk a tárolt eljárást a Visual Studio O/R Designerére, ami generál nekünk egy éppen megfelelő metódust. Szinte eláll a szívünk, amikor meglátjuk az így előállt C# metódust és már hívjuk is lelkesen, hiszen int a visszatérési érték:

    NorthwindDataContext dc = new NorthwindDataContext();
    int i = dc.GetCustomerCount();
    Console.WriteLine( i );

Bár a tárolt eljárás szinte művészien tökéletes, szomorúan konstatáljuk, hogy bizony mindig nullát ad vissza. Nézzük meg a generált metódus belsejét:

    [StoredProcedure( Name = "dbo.GetCustomerCount" )]
    public int GetCustomerCount()
    {
        IExecuteResults result = this.ExecuteMethodCall(
            this,
            (MethodInfo) MethodInfo.GetCurrentMethod() );
        return ( (int) ( result.ReturnValue ) );
    }

A kérdés – amire az MSDN-ből aligha kapunk választ a mostani béta változatban -, hogy mi az az IExecuteResults és mit tud a ReturnValue tulajdonsága? Némi Reflectorozással odáig sikerült eljutnom, hogy a DataContext.ExecuteMethodCall meghívja az aktuális provider ExecuteNonQuery metódusát, de mivel az is interfész alapú (IProvider), így az implementációval először nem sokáig jutottam. (Ezen a ponton arra tippeltem, hogy ez az ExecuteNonQuery ugyanúgy viselkedik, mint az IDbCommand esetén és az "érintett sorok" – rows affected – számát adja vissza. Mint kiderült nem egészen…)

Aztán tovább ásva megtaláltam a System.Data.Linq.SqlClient.SqlProvider osztályt, ahol az ExecuteNonQuery egy SqlExecuteResults típussal tér vissza, ami implementálja az IExecuteResults interfészt. Már csak az maradt kérdés, hogy hogyan kap értéket a ReturnValue tulajdonság? A konstruktorból kiderül, hogy a @RETURN_VALUE paramétertől.

Na de ki beszél itt SQL paraméterről, hiszen ennek a tárolt eljárásnak nincs se input, se output paramétere! Nosza kérdezzük meg, mi megy az adatbázisba, amihez használhatjuk a DataContext.Log tulajdonságát. Az eredmény:

    EXEC @RETURN_VALUE = [dbo].[GetCustomerCount]
    -- @RETURN_VALUE: Output Int (Size = 0; Prec = 0; Scale = 0) NOT NULL []

Hűha! Irány az SQL Server Books Online, hányféleképpen lehet beállítani egy tárolt eljárás visszatérési értékét? Nekem SELECT-tel nem sikerült, maradt a RETURN, amihez át kellett írni a tárolt eljárást, például így:

    DECLARE @Result int
    SELECT @Result = Count(*) FROM Customers
    RETURN @Result

Ez engem zavar, ezért kedves SQL guruk, mondjatok valami egyszerűbbet!

Ami pedig az MSDN-t illeti, egyetlen rövid mondat rengeteg időt megspórolhatott volna. Persze, tudom, béta termék, meg ez csak egy metódus a sok közül, de akkor is. Gondoltam egyet és megkeresetem az ExecuteMethodCall oldalát az MSDN Wikiben: abban reménykedtem, hogy ha ide megírom a felfedezéseimet, az majd segít másoknak és valamilyen formában bekerül az RTM dokumentációba. Nos, erről lepattantam, egyrészt mert úgy látszik a béta dokumentációhoz nem lehet hozzáírni, másrészt pedig ennek a metódusnak a leírása angolul nem található meg, csak japánul smile_sniff Ez remélem átmeneti bug és nem feature smile_sad

 

Technorati tags:
Reklámok

One thought on “DLINQ: Egyszerű tárolt eljárások esete az MSDN-nel

  1. Zsolt

    Érdekelne, mit csinál, ha nem int a skalár típusa? Akkor nem tudja eljátsztani a visszatérési érték mesét, mert az csak int32 típusú lehet.Más. Nincs email vagy egyéb lehetőség, hogy jelzést kapjak, ha hozzászólnak egy bejegyzéshez?

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s