2009-02-26 10 views
9

Ho un progetto di SqlServer con un test molto semplice per un valori di tabella-Function: -SqlFunction non riesce ad aprire connessione di contesto, nonostante DataAccessKind.Read presente

[SqlFunction(TableDefinition = "forename nvarchar(50)", FillRowMethodName = "TestFillRow", DataAccess = DataAccessKind.Read)] 
public static IEnumerable TestConn(int ID) 
{ 
    using (SqlConnection con = new SqlConnection("context connection=true")) 
    { 
     //con.Open(); 
     yield return "Anthony"; 
    } 
} 

public static void TestFillRow(object obj, out string forename) 
{ 
    forename = (string)obj; 
} 

nota l'Open sulla connessione è attualmente commentata. Una volta implementato posso eseguire questo in SQL: -

SELECT * FROM [dbo].[TestConn](1) 

Tutto funziona bene.

Ora togliere il commento alla con.open() e non riesce con: -

accesso ai dati non è consentito in questo contesto . Sia il contesto è una funzione o metodo non contrassegnato con DataAccessKind.Read o SystemDataAccessKind.Read, è un callback per ottenere dati da FillRow metodo di una tabella funzione valutata, o è un metodo di convalida UDT.

Non vedo quale sia il problema, la funzione TestConn ha DataAccessKind.Read.

Qualcuno sa di altri motivi per ottenere questo errore?

risposta

12

Il problema è il seguente:

  1. SQLCLR non consente alcun accesso ai dati all'interno TestFillRow

  2. Anche se "sembra" come i tuoi dati di accesso TestFillRow doesnt, il modo in cui il compilatore traduce il codice con le istruzioni "yield" è in realtà rimandando la sua esecuzione fino alla prima chiamata .MoveNext() all'iteratore. Pertanto la seguente dichiarazione:

    using (SqlConnection con = new SqlConnection("context connection=true"))   
    

    viene eseguito all'interno TestFillRow ... che è illegale.

Non utilizzare dei rendimenti; caricare invece l'intero risultato su List<> e restituire l'elenco alla fine della funzione UD.

+0

Un'accettazione molto tardiva e in aumento, (richiesto mi vergogno di dire con un voto negativo sulla mia domanda). Hai perfettamente ragione che il nulla funzioni fino a Movenext. Ho persino parlato di questo comportamento qui: - http://geekswithblogs.net/codingbloke/archive/2010/09/12/simple-asynchronous-operation-runner-ndash-part-1.aspx ma non l'ho fatto chiaramente t vedere la connessione tra loro fino ad ora. – AnthonyWJones

+0

Vedere Errore di connessione relativo alle limitazioni di FillRow: http://connect.microsoft.com/SQLServer/feedback/details/442200/sql-server-2008-clr-tvf-data-access-limitations-break-existing-code – piers7

+2

È non il problema che la connessione * si apre * all'interno di 'TestFillRow'.Anche se fornisci la tua implementazione "entusiasta" di un enumeratore che apre la connessione e recupera la prima riga all'interno del metodo principale, quell'enumeratore non funzionerà da 'TestFillRow' perché la connessione sarà stata forzatamente chiusa. – GSerg

1

"SQLCLR non consente l'accesso ai dati all'interno di TestFillRow" è un errore.

Se non si utilizza la stringa di connessione context connection = true, è possibile accedere ai dati all'interno del metodo FillRow.