Does Oracle ManagedDataAccess.EntityFramework Database.SqlQuery bind parameters by position?

I have the following code:

        var query = Database.SqlQuery<int>(@"

            SELECT CASE WHEN EXISTS (
                SELECT 1 
                FROM v$session v, UsersXxxx u
                WHERE v.Client_Info LIKE u.UserName || ';%' 
                AND v.UserName = :schemaName
                AND u.SchemaName = :schemaName
                AND v.module = 'XXXX.exe' 
                AND u.UserKey = :userKey)
            THEN 1 ELSE 0 END AS LoggedIn FROM DUAL",

            new OracleParameter("schemaName", schemaName),
            new OracleParameter("userKey", userKey));

        return query.First() != 0;

What creates "ORA-01008: not all related variables." I suspected something had happened with the way the variables were related, and ended up trying to do this:

        var query = Database.SqlQuery<int>(@"

            SELECT CASE WHEN EXISTS (
                SELECT 1 
                FROM v$session v, UsersXxxx u
                WHERE v.Client_Info LIKE u.UserName || ';%' 
                AND v.UserName = :schemaName
                AND u.SchemaName = :schemaName
                AND v.module = 'XXXX.exe' 
                AND u.UserKey = :userKey)
            THEN 1 ELSE 0 END AS LoggedIn FROM DUAL",

            new OracleParameter("asdf", schemaName),
            new OracleParameter("fdsa", schemaName),
            new OracleParameter("userKey", userKey));

        return query.First() != 0;

What works like a charm! I poked the docs and found an advertising message that said:

"Binding scalar parameters are supported by ODP.NET and Entity Framework. Entity Framework supports parameter binding by name. Position binding is not supported."

Somehow I think that the documents are lying to me, and he is trying to bind by position. I remember how this was fixed before EF support, but I can’t remember what the fix was, especially how to apply the same method to EF.

, kludgy, , - ? , ?

+4
2

, Database.SqlQuery CreateCommand DbConnection. ODP.NET OracleCommand, (BindByName = false).

, . SqlQuery, OracleCommand BindByName = true, do ExecuteReader ObjectContext.Translate :

public static class EFExtensions
{
    public static IEnumerable<T> DbQuery<T>(this DbContext db, string sql, params object[] parameters)
    {
        if (parameters != null && parameters.Length > 0 && parameters.All(p => p is OracleParameter))
            return OracleDbQuery<T>(db, sql, parameters);
        return db.Database.SqlQuery<T>(sql, parameters);
    }

    private static IEnumerable<T> OracleDbQuery<T>(DbContext db, string sql, params object[] parameters)
    {
        var connection = db.Database.Connection;
        var command = connection.CreateCommand();
        ((OracleCommand)command).BindByName = true;
        command.CommandText = sql;
        command.Parameters.AddRange(parameters);
        connection.Open();
        try
        {
            using (var reader = command.ExecuteReader())
            using (var result = ((IObjectContextAdapter)db).ObjectContext.Translate<T>(reader))
            {
                foreach (var item in result)
                    yield return item;
            }
        }
        finally
        {
            connection.Close();
            command.Parameters.Clear();
        }
    }
}

,

context.Database.SqlQuery<..>(...)

context.DbQuery<..>(...)
+7

web.config, BindByName.

<oracle.manageddataaccess.client>
<version number="*">
  <settings>
    <setting name="BindByName" value="true" />
  </settings>
</version>
</oracle.manageddataaccess.client>
+1

Source: https://habr.com/ru/post/1610807/


All Articles