如何从Entity Framework 6(数据库优先)和Npgsql执行存储过程?
How to execute stored procedure from Entity Framework 6 (database first) and Npgsql?
这是一个错误吗?
我的组件是:
- .NET 4.6.1
- Entity Framework 6.0
- Npgsql 3.0.5
- PostgreSQL 9.5
首先,我在 PostgreSQL 9.5
中创建了一个 table 和存储过程
CREATE TABLE hello
(
msg text
)
WITH (
OIDS=FALSE
);
ALTER TABLE hello
OWNER TO postgres;
CREATE OR REPLACE FUNCTION sayhello()
RETURNS SETOF hello AS
$BODY$
select
*
from version()
$BODY$
LANGUAGE sql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION sayhello()
OWNER TO postgres;
其次,我转到.edmx
文件(Entity Framework6.0),选择"update from database",选择新的table "hello"和新存储的程序,"sayhello".
模型浏览器现在显示新的 table 实体和导入的函数。
三、在WCF文件中添加新程序:
public string SayHello()
{
using (var ctx = new chaosEntities())
{
var x = ctx.sayhello();
return "Hello";
}
}
将 WCF 服务设置为启动项目并开始调试。
出现 WCF 测试客户端。从 WCF 服务执行 SayHello()
导致:
public virtual ObjectResult<hello> sayhello()
{
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<hello>("sayhello");
}
执行时,我得到:
An exception of type 'System.Data.Entity.Core.EntityCommandCompilationException'
occurred in EntityFramework.dll but was not handled in user code
Additional information: An error occurred while preparing the command
definition. See the inner exception for details.
Inner Exception is: {"Value does not fall within the expected range."}
由于我有数百个存储过程,因此非常感谢任何有关如何解决此问题的帮助。
TIA
注意:我怀疑问题出在 NpgsqlServices.TranslateCommandTree,但我只是猜测。
我永远无法让它按照我希望的方式工作(通过 EntityFramework),所以我最终这样做了。我肯定愿意接受更好的解决方案!
下面的代码直接调用 Npgsql 来避免整个 EntityFramework 事情。
public string SayHello()
{
using (var ctx = new chaosEntities())
{
var b = ctx.Database.Connection.ConnectionString;
using (var conn = new Npgsql.NpgsqlConnection(connectionString: b))
{
conn.Open();
using (var tran = conn.BeginTransaction())
using (var command = conn.CreateCommand())
{
command.CommandText = "sayhello";
command.CommandType = CommandType.StoredProcedure;
var g = (string)command.ExecuteScalar();
return g;
}
}
}
}
这是一个错误吗?
我的组件是:
- .NET 4.6.1
- Entity Framework 6.0
- Npgsql 3.0.5
- PostgreSQL 9.5
首先,我在 PostgreSQL 9.5
中创建了一个 table 和存储过程CREATE TABLE hello
(
msg text
)
WITH (
OIDS=FALSE
);
ALTER TABLE hello
OWNER TO postgres;
CREATE OR REPLACE FUNCTION sayhello()
RETURNS SETOF hello AS
$BODY$
select
*
from version()
$BODY$
LANGUAGE sql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION sayhello()
OWNER TO postgres;
其次,我转到.edmx
文件(Entity Framework6.0),选择"update from database",选择新的table "hello"和新存储的程序,"sayhello".
模型浏览器现在显示新的 table 实体和导入的函数。
三、在WCF文件中添加新程序:
public string SayHello()
{
using (var ctx = new chaosEntities())
{
var x = ctx.sayhello();
return "Hello";
}
}
将 WCF 服务设置为启动项目并开始调试。
出现 WCF 测试客户端。从 WCF 服务执行 SayHello()
导致:
public virtual ObjectResult<hello> sayhello()
{
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<hello>("sayhello");
}
执行时,我得到:
An exception of type 'System.Data.Entity.Core.EntityCommandCompilationException' occurred in EntityFramework.dll but was not handled in user code
Additional information: An error occurred while preparing the command definition. See the inner exception for details.
Inner Exception is: {"Value does not fall within the expected range."}
由于我有数百个存储过程,因此非常感谢任何有关如何解决此问题的帮助。
TIA
注意:我怀疑问题出在 NpgsqlServices.TranslateCommandTree,但我只是猜测。
我永远无法让它按照我希望的方式工作(通过 EntityFramework),所以我最终这样做了。我肯定愿意接受更好的解决方案!
下面的代码直接调用 Npgsql 来避免整个 EntityFramework 事情。
public string SayHello()
{
using (var ctx = new chaosEntities())
{
var b = ctx.Database.Connection.ConnectionString;
using (var conn = new Npgsql.NpgsqlConnection(connectionString: b))
{
conn.Open();
using (var tran = conn.BeginTransaction())
using (var command = conn.CreateCommand())
{
command.CommandText = "sayhello";
command.CommandType = CommandType.StoredProcedure;
var g = (string)command.ExecuteScalar();
return g;
}
}
}
}