数据库是oracle,dbms_job在sys用户下,我在另一个用户sj下直接用语句调用这个存储过程,如下所示:
System.Data.EntityClient.EntityParameter parameters = new System.Data.EntityClient.EntityParameter("job", DbType.Int32);
parameters.Value = jobId;
_dal.ExecuteFunction("dbms_job.run", parameters);
其中ExecuteFunction是自定义函数:
int IRepository.ExecuteFunction1(string functionName, params System.Data.EntityClient.EntityParameter[] parameters)
{
var cmd = this.lbc.Connection.CreateCommand();
cmd.CommandText = functionName;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddRange(parameters);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
return 1;
}
当执行这句ExecuteNonQuery()时就报错:在当前工作区中找不到为 FunctionImport 指定的容器“dbms_job”,有谁遇到过这种问题吗?
dbms_job 是啥?
oracle中执行job的存储过程
@惊梦无痕:
The ExecuteFunction method is a helper method that is used to execute stored procedures or functions that are defined in the data source and expressed in the conceptual model. The Entity Data Model tools generate a method for each FunctionImport Element in the conceptual model. These methods call a strongly-typed ExecuteFunction to return a typed ObjectResult<T>. For more information, see Application Code using Stored Procedures (Enity Framework).
你是不是需要先把存储过程拖到你的模型中来。
@Launcher: 直接用语句也需要建模型吗,我的ExecuteFunction是自定义函数:
var cmd = this.lbc.Connection.CreateCommand();
cmd.CommandText = functionName;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddRange(parameters);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
另外如果要建立模型,那一定要在sys用户下建立模型了,能在我登录的用户空间下建立吗
@惊梦无痕: 你可以把 CreateCommand 返回的对象的类型显示出来看看。直接使用 ODP.NET 来调用存储过程,不需要建模,但是从你的错误提示(在当前工作区中找不到为 FunctionImport 指定的容器“dbms_job”)中看到了 EF 中的关键字“FunctionImport”和你提问中提及到“entity framework”,因此我才按照 EF 的范围来解答。
@Launcher: 我是在EF中直接用语句来调用dbms_job.run的,对象类型好像没什么问题,可是最后报错就是(在当前工作区中找不到为 FunctionImport 指定的容器“dbms_job”),很郁闷。
@惊梦无痕: 请问,你到底是用的 ObjectContext.ExecuteFunction 方法,还是用的 DbCommand.ExecuteNonQuery 方法,或是别的?请你指明!
@Launcher: ExecuteFunction是我另外写的自定义函数,或者可以把ExecuteFunction理解成ExecuteProcedure,而这个自定义函数中通过cmd.ExecuteNonQuery();来调用存储过程,这样是否可以清楚点理解,整个语句其实就是:
System.Data.EntityClient.EntityParameter parameters = new System.Data.EntityClient.EntityParameter("job", DbType.Int32);
parameters.Value = 68;
var cmd = this.objectContext.Connection.CreateCommand();
cmd.CommandText = "dbms_job.run";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddRange(parameters);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
@惊梦无痕: 你参照这篇文章:http://www.oracle.com/technetwork/cn/testcontent/o23odp-084525-zhs.html
写个 Console 程序,用你在 EF 中配置的连接字符串测试下 dbms_job.run 存储过程能否正确调用。
你也可以做如下尝试:http://msdn.microsoft.com/zh-cn/library/vstudio/bb896231(v=vs.100).aspx
按照这篇文章看看能否添加 dbms_job.run 存储过程到 edmx 中,如果不能,请考虑新建一个连接,使用 sys 用户创建 edmx,然后重复上面的操作看看能否添加 dbms_job.run 存储过程。
@惊梦无痕: 我看了下 objectContext.Connection.CreateCommand() 返回的是 EntityCommand 类型,这同我们经常使用的 OracleCommand 类是不一样的,前者需要 FunctionImport,也就是你需要在 EDMX 中添加存储过程。
因此,你要么把存储过程加到 EDMX 中来,要么使用 ODP.NET 来实现存储过程调用。
@Launcher: 哦,这样啊,那我去试试看,谢谢啊。这个问题烦了我好长时间了。刚学EF没多久,以前都是用原生态的sql,很多东西还不是很明白,不知道有没有什么书可以推荐一下学习。
@惊梦无痕: 没关系,我还没学过 EF,是直接看的 MSDN 和源码。
http://www.cnblogs.com/yipeng-yu/archive/2013/02/28/2936326.html
dbms_job有没有前缀(schema),有的话,加上试试
什么意思,是schema.dbms_job吗?还是不行的啊
@惊梦无痕: 在Oracle中存储过程是如何定义的?
@dudu: 这是一个系统package,sys用户下的,专门用来管理job的。
PACKAGE sys.dbms_job IS
PROCEDURE run ( job IN BINARY_INTEGER,force IN BOOLEAN DEFAULT FALSE);
end;
@惊梦无痕: 试试sys.dbms_job.run
@dudu: 试过了,结果就报:EntityCommand.CommandText 的值对 StoredProcedure 命令无效。EntityCommand.CommandText 值必须为“ContainerName.FunctionImportName”形式。折磨人啊
@惊梦无痕: 建议试试 Database.ExecuteSqlCommand()
@dudu: oracle中没有这个语句啊
@惊梦无痕: 你用的是Code First吗?
@dudu: database first
The EntityCommand.CommandText value must be of the form 'ContainerName.FunctionImportName'
i have two flies named "Model1.edmx" occured is error.
chang one of files name .that error is fix