如何从Entity Framework 6(数据库优先)和Npgsql执行存储过程?

时间:2016-02-28 10:18:05

标签: entity-framework postgresql wcf stored-procedures npgsql

这是一个错误吗?

我的组件是:

  1. .NET 4.6.1
  2. Entity Framework 6.0
  3. Npgsql 3.0.5
  4. PostgreSQL 9.5
  5. 首先,我在PostgreSQL 9.5中创建了一个表和存储过程

    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 Framework 6.0),选择"从数据库"更新,选择新表"你好"和新的存储过程," sayhello"。

    模型浏览器现在显示新表实体和导入的函数。

    第三步,向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");
    }
    

    执行此操作时,我得到:

      

    类型&#39; System.Data.Entity.Core.EntityCommandCompilationException&#39;的异常   发生在EntityFramework.dll中但未在用户代码中处理

         

    其他信息:准备命令时发生错误   定义。有关详细信息,请参阅内部异常。

         

    内部例外是:{&#34;价值不在预期范围内。&#34;}

    由于我有几百个存储过程,因此非常感谢任何有关如何解决此问题的帮助。

    TIA

    注意:我怀疑问题出在NpgsqlServices.TranslateCommandTree上,但我只是在猜测。

1 个答案:

答案 0 :(得分:1)

我永远无法以我希望的方式工作(通过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;
                    }
                }
            }
        }