Łączenie Oracle przy użyciu ODP.NET z Enterprise Library DAAB

Nasza aplikacja korzysta z Enterprise Library DAAB do obsługi baz danych Oracle i SQL.

Jedną z procedur składowanych jest przesyłanie obrazu do tabeli. Jest to pole BLOB, a parametr jest ustawiony na DbType.Binary.

Ta funkcjonalność działa bez problemu dla SQL, ale gdy przychodzi do Oracle, trafiłem na problem z limitem rozmiaru 32K.

Jak zasugerowano w SO, przeniosłem kod do ODP.NET, ale wciąż mam ten sam problem.

Ustawienie pliku My App.config:

<configuration>
<configSections>
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<dataConfiguration defaultDatabase="Oracle">
    <providerMappings>
        <add databaseType="Microsoft.Practices.EnterpriseLibrary.Data.Oracle.OracleDatabase, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
            name="Oracle.DataAccess.Client" />
    </providerMappings>
</dataConfiguration>
<connectionStrings>
    <add name="Oracle" connectionString="Data Source=MYORACSER;USER ID=UNAME;PASSWORD=MYPWD;"
        providerName="Oracle.DataAccess.Client" />
</connectionStrings>

W moim kodzie aplikacji korzystam z biblioteki korporacyjnej, aby uzyskać dostęp do bazy danych

 Database db = DatabaseFactory.CreateDatabase(); 
 DbCommand cmd = db.GetStoredProcCommand(spName);
 cmd.CommandType = CommandType.StoredProcedure;
 db.AddInParameter(cmd, "DOCIMAGE", DbType.Binary, GetByteArrayFromFile(filePath));
 db.AddOutParameter(cmd, "return_value", DbType.Int32, 128);
 int row = db.ExecuteNonQuery(cmd);

Mam następujące zespoły wymienione w moim projekcie:

Teraz, gdy uruchomię aplikację, Ent Lib DAAP powinien używać Oracle.DataAccess.Client, ale nadal jest podłączony do bazy danych Oracle poprzez System.Data.OracleClient. Więc limit 32K nadal istnieje.

Dlaczego nie korzysta z Oracle Data Provider, jak wyraźnie wspomniałem w App.config?

W jednym poście wspomniano, że należy użyć następującego fragmentu kodu jako obejścia,

DbProviderFactory providerFactory = DbProviderFactories.GetFactory("Oracle.DataAccess.Client");
Database db = GenericDatabase(connectionString, providerFactory); 

Ten wydaje się działać.

Ale instancja bazy danych ma GenericDatabase zamiast OracleDatabase, może to dlatego nawet ten wyjątek nadal działa, gdy rozmiar pliku przekracza 32K.

Jak korzystać z ODP.NET z biblioteką Enterprise w przypadku problemu z limitem rozmiaru 32K?

ZDECYDOWANY:

podążałemhridya przejść przez. Jak wspomniał, były błędy komentarza XML, które można wyłączyć(Popatrz tutaj). Wystąpiło również kilka konfliktów przestrzeni nazw, które rozwiązano, wybierając Oracle.DataAccess.Client. Po tym skompilował się pomyślnie.

Oto mój fragment kodu z przykładowej aplikacji, którą zrobiłem, aby przetestować zmiany. (Przykładowe rozwiązanie odwołuje się teraz do nowych skompilowanych bibliotek danych i bibliotek wspólnych).

Database db = DatabaseFactory.CreateDatabase();
            DbCommand cmd = db.GetStoredProcCommand(sqlCode);
            cmd.CommandType = CommandType.StoredProcedure;
            db.AddInParameter(cmd, "DOCIMAGE", DbType.Binary, GetByteArrayFromFile(filePath));
            db.AddOutParameter(cmd, "return_value", DbType.Int32, 128);
            int rowID = db.ExecuteNonQuery(cmd);

Sprawdziłem obiekt polecenia, teraz jest on typu Oracle.DataAccess.Client.OracleCommand, podczas gdy poprzednio był to System.Data.OracleClient.OracleCommand.

Pamiętaj, ponieważ już zmodyfikowałem DAAB, aby używać ODP.NET, nie muszę ustawiać dostawcy jawnie w pliku konfiguracyjnym za pomocą tagu providerMappings.

Ale wciąż otrzymuję ten sam błąd, gdy rozmiar pliku przekracza 32K, wkroczenie do wiersza kodu po wierszu ujawniło, że problem dotyczy DbType.Binary. Nie został zmieniony na właściwy OracleDbType.

Aby to działało, dodałem jeszcze jedną poprawkę kodu w Projekcie danych Enterprise Lib.

Plik:Oracle OracleData Database.cs

Metoda:AddParameter

Oryginalny kod:

public override void AddParameter(DbCommand command, string name, DbType dbType, int size,
        ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn,
        DataRowVersion sourceVersion, object value)
    {
        if (DbType.Guid.Equals(dbType))
        {
            object convertedValue = ConvertGuidToByteArray(value);

            AddParameter((OracleCommand)command, name, OracleDbType.Raw, 16, direction, nullable, precision,
                scale, sourceColumn, sourceVersion, convertedValue);

            RegisterParameterType(command, name, dbType);
        }
        else
        {
            base.AddParameter(command, name, dbType, size, direction, nullable, precision, scale,
                sourceColumn, sourceVersion, value);
        }
    }

Dodano warunek dla DbType.Binary

Zmodyfikowany kod:

public override void AddParameter(DbCommand command, string name, DbType dbType, int size,
        ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn,
        DataRowVersion sourceVersion, object value)
    {
        if (DbType.Guid.Equals(dbType))
        {
            object convertedValue = ConvertGuidToByteArray(value);

            AddParameter((OracleCommand)command, name, OracleDbType.Raw, 16, direction, nullable, precision,
                scale, sourceColumn, sourceVersion, convertedValue);

            RegisterParameterType(command, name, dbType);
        }
        else if(DbType.Binary.Equals(dbType))
        {
            AddParameter((OracleCommand)command, name, OracleDbType.Blob, size, direction, nullable, precision,
                scale, sourceColumn, sourceVersion, value);

        }
        else
        {
            base.AddParameter(command, name, dbType, size, direction, nullable, precision, scale,
                sourceColumn, sourceVersion, value);
        }
    }

Nie wiem Jeśli jest to właściwy sposób lub inne eleganckie obejście jest już dostępne. Ale to zadziałało.

questionAnswers(2)

yourAnswerToTheQuestion