Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Oracle ManagedDataAccess.EntityFramework Database.SqlQuery按位置列出的绑定参数?_C#_Oracle_Entity Framework - Fatal编程技术网

C# Oracle ManagedDataAccess.EntityFramework Database.SqlQuery按位置列出的绑定参数?

C# Oracle ManagedDataAccess.EntityFramework Database.SqlQuery按位置列出的绑定参数?,c#,oracle,entity-framework,C#,Oracle,Entity Framework,我有以下代码: var query = Database.SqlQuery<int>(@" SELECT CASE WHEN EXISTS ( SELECT 1 FROM v$session v, UsersXxxx u WHERE v.Client_Info LIKE u.UserName || ';%' AN

我有以下代码:

        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;
这将生成一个ORA-01008:并非所有变量都绑定。我怀疑变量绑定的方式出了问题,最后尝试了以下方法:

        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;
这就像一个符咒!我翻了翻文档,发现了一个广告,上面写着:

ODP.NET和实体框架支持绑定标量参数。在实体框架中,支持按名称绑定参数。不支持按位置绑定

不知何故,我认为医生们在骗我,他们试图通过立场来约束我。我记得很久以前在EF支持之前修复过一次,但我不记得修复是什么,更不用说如何在EF中应用相同的技术了

我的解决方法虽然很难实现,但是否有一个选项可以让它通过名称而不是位置绑定?如果是,那是什么?

问题是Database.SqlQuery方法使用底层DbConnection的CreateCommand方法。在ODP.NET中,这将导致一个OracleCommand,默认情况下,该命令通过位置BindByName=false绑定参数

这种行为是不可配置的,也没有改变它的好地方。作为一种解决方法,我可以建议使用自定义SqlQuery方法替换,该方法将创建BindByName=true的OracleCommand,执行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<..>(...)

在托管驱动程序的最新版本中,您可以添加默认情况下将BindByName设置为true的web.config条目

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

我会尽我所能去发现:/@Halter,不,我还没有找到如何让这项工作按我想要的方式进行。解决方法仍然存在,老实说,我几乎放弃了。知道这一点当然还是很好的。谢谢没问题,这种解决方法对我来说根本不起作用:詹姆斯,你知道你使用的是什么版本的EF吗?@Halter最终的另一个选择是使用你自己的SqlQuery方法替换,它创建一个正确的命令,然后使用旧的good ObjectContext。翻译以获得结果。非常感谢兄弟!!!在配置中,默认情况下将bindbyname设置为true真是太神奇了。你太棒了