Frage

Meine Website wird mit Enterprise Library v 5.0. Vor allem der DAAB. Einige Funktionen wie ExecuteScalar, ExecuteDataset arbeiten wie erwartet. Die Probleme auftreten, wenn ich auf den Einsatz Leser

starten

Ich habe diese Funktion in meiner enthält Klasse:

Public Function AssignedDepartmentDetail(ByVal Did As Integer) As SqlDataReader
    Dim reader As SqlDataReader
    Dim Command As SqlCommand = db.GetSqlStringCommand("select seomthing from somewhere where something = @did")
    db.AddInParameter(Command, "@did", Data.DbType.Int32, Did)
    reader = db.ExecuteReader(Command)
    reader.Read()
    Return reader
End Function

Dies ist aus meiner aspx.vb wie so genannt:

reader = includes.AssignedDepartmentDetail(Did)
If reader.HasRows Then
    TheModule = reader("templatefilename")
    PageID = reader("id")
Else
    TheModule = "#"
End If

Dies gibt die folgenden Fehler auf db.ExecuteReader Zeile:

Kann nicht Gussobjekt des Typs 'Microsoft.Practices.EnterpriseLibrary.Data.RefCountingDataReader' eingeben 'System.Data.SqlClient.SqlDataReader'.

Schuppen Kann jemand irgendein Licht auf, wie ich mich über diese Arbeit zu bekommen. Werde ich immer auf Probleme stoßen, wenn sie mit Lesern über EntLib zu tun?

War es hilfreich?

Lösung

Ich glaube, ich habe eine funktionierende Lösung.

enter code here

    ' Create the Database object, using the default database service. The
    ' default database service is determined through configuration.
    Dim db As Microsoft.Practices.EnterpriseLibrary.Data.Database = EnterpriseLibraryContainer.Current.GetInstance(Of Microsoft.Practices.EnterpriseLibrary.Data.Database)(DatabaseName)

    Dim dbCommand As DbCommand
    dbCommand = db.GetStoredProcCommand(StoredProcedureName)

    'create a new database connection based on the enterprise library database connection
    Dim dbConnection As System.Data.Common.DbConnection
    dbConnection = db.CreateConnection
    dbConnection.Open()

    'set the dbCommand equal to the open dbConnection
    dbCommand.Connection = dbConnection

    'return a ADO sqlDatareader but still managed by the EnterpriseLibrary
    Return dbCommand.ExecuteReader(CommandBehavior.CloseConnection)

Andere Tipps

würde ich mit dieser Implementierung vorsichtig sein. Es ist ein Thread auf der Enterprise Library Codeplex-Site, die die backgound für das erklärt: http://entlib.codeplex.com/Thread/View.aspx?ThreadId= 212973

Chris Tavares erklärt, dass es nicht gut ist, nur die .InnerReader zurückkehren, weil dann die Verbindung von Enterprise Library Tracking abgeworfen (seine Antwort vom 20. Mai, 17.39 Uhr): „Dieser Ansatz wird vollständig schrauben Sie Ihre Verbindung Verwaltung. Der ganze Grund für die Umhüllung so ist, dass wir zusätzlichen Code sauber Sachen zu entsorgen Zeit bis ausführen kann. Die innere Leser Grabbing und die äußere werfen leckt Verbindungen! „

Also ja, das ist ein bisschen wie ein Schmerz zu behandeln, die wir in der gleichen Situation sind.

Viele Grüße, Mike

ExecuteReader in Enterprise Library hüllt IDataReader in RefCountingDataReader dass als SqlDataReader Geräte IDataReader Schnittstelle.

RefCountingDataReader hat InnerReader Eigenschaft, die Sie SqlDataReader werfen können. Das folgende Beispiel ist in C #, aber Sie können es zu VB.NET leicht umwandeln.

SqlDataReader reader;
reader = ((RefCountingDataReader)db.ExecuteReader(command)).InnerReader as SqlDataReader;
if (reader != null)
    reader.Read();
return reader;

Hope es hilft

Ich habe Verbindungen undicht, weil alle meine DA Methoden einen SqlDataReader erfordern. Jetzt muß ich die inneren RefCountingDataReader zurückkehren und kann niemals den äußeren Leser schließen. Die alte Enterprise Library funktioniert gut mit einem SqlDataReader zurück.

Ich habe berücksichtigt die Kommentare und Code von ctavars veröffentlicht unter http: //entlib.codeplex. com / Diskussionen / 212973 und http://entlib.codeplex.com/discussions/211288 in dem folgenden generischen Ansatz führt, das ein SQL-Datenleser zu erhalten.

Generell Sie IDataReader in der using-Anweisung verwenden, verwenden Sie dann, dass der Bezug direkt, wenn Sie können. Rufen Sie AsSqlDataReader auf es, wenn Sie brauchen etwas SQL-spezifisch ist.

Fügen Sie diese Erweiterung Klasse irgendwo:

/// <summary>
/// Obtains an <see cref="SqlDataReader"/> from less derived data readers in Enterprise Library
/// </summary>
/// <remarks>
/// See http://entlib.codeplex.com/discussions/212973 and http://entlib.codeplex.com/discussions/211288
/// for a discussion of why this is necessary
/// </remarks>
public static class SqlDataReaderExtension
{
    /// <summary>
    /// Allows the internal <see cref="SqlDataReader"/> of a <see cref="RefCountingDataReader"/> to be accessed safely
    /// </summary>
    /// <remarks>
    /// To ensure correct use, the returned reference must not be retained and used outside the scope of the input
    /// reference. This is so that the reference counting does not get broken. In practice this means calling this method
    /// on the base reader every time a reference to it is required.
    /// </remarks>
    public static SqlDataReader AsSqlDataReader(this RefCountingDataReader reader)
    {
        return (SqlDataReader)(reader.InnerReader);
    }

    /// <summary>
    /// Allows the internal <see cref="SqlDataReader"/> of a <see cref="IDataReader"/> to be accessed safely
    /// </summary>
    /// <remarks>
    /// To ensure correct use, the returned reference must not be retained and used outside the scope of the input
    /// reference. This is so that the reference counting does not get broken. In practice this means calling this method
    /// on the base reader every time a reference to it is required.
    /// </remarks>
    public static SqlDataReader AsSqlDataReader(this IDataReader reader)
    {
        return (SqlDataReader)(((RefCountingDataReader)(reader)).InnerReader);
    }
}

... dann Daten mit einem SQLReader zu lesen, etwas tun, wie folgt aus:

using (IDataReader reader = db.ExecuteReader(command))
{
    while (reader.Read())
    {
        reader.GetInt32(reader.GetOrdinal("SomeColumn")),
        reader.GetInt32(reader.GetOrdinal("SomeOtherColumn")),
        reader.GetInt32(reader.GetOrdinal("SomeFurtherColumn")),
        // Obtain the SQL data reader each time it is used
        // (Note that GetDateTimeOffset is not on the standard IDataReader)
        reader.AsSqlDataReader().GetDateTimeOffset(reader.GetOrdinal("SQLSpecificColumn"))
        reader.AsSqlDataReader().GetDateTimeOffset(reader.GetOrdinal("AnotherSQLSpecificColumn"))
        reader.GetString(reader.GetOrdinal("SomeAdditionalColumn"))
    }
}

Sie sollten die Schnittstelle verwenden, nicht die konkrete Klasse.

Public Function AssignedDepartmentDetail(ByVal Did As Integer) As IDataReader
    Dim reader As IDataReader
    Dim Command As SqlCommand = db.GetSqlStringCommand("select seomthing from somewhere where something = @did")
    db.AddInParameter(Command, "@did", Data.DbType.Int32, Did)
    reader = db.ExecuteReader(Command)
    reader.Read()
    Return reader
End Function

und die Nutzung. Persönlich würde ich nie eine Datareader in einer Präsentationsschicht-Seite verwenden, aber zu jeder seine / ihre eigenen, denke ich.

Private Const TemplateFileName_Select_Column_Ordinal As Integer = 0
Private Const Id_Select_Column_Ordinal As Integer = 1

Private Sub DoSomething()
dim reader as IDataReader
reader = includes.AssignedDepartmentDetail(Did)
If reader.HasRows Then
    TheModule = reader(TemplateFileName_Select_Column_Ordinal)
    PageID = reader(Id_Select_Column_Ordinal)
Else
    TheModule = "#"

    reader.Close()  ''Dude, close your reader(s)

End If
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top