实体框架数据库第一个存储过程具有不同的返回类型

时间:2014-10-10 12:10:23

标签: c# entity-framework stored-procedures

我有一个名为CreatePrice的存储过程,并已将其添加到edmx文件(数据库优先)我可以在模型浏览器中的函数导入下看到它,一切都很好。生成的函数如下所示:

 public virtual ObjectResult<CreatePrice_Result> CreatePrice(string type, string code, string userName, Nullable<bool> export)
{
    var typeParameter = type != null ?
        new ObjectParameter("Type", type) :
        new ObjectParameter("Type", typeof(string));

    var codeParameter = code != null ?
        new ObjectParameter("Code", code) :
        new ObjectParameter("Code", typeof(string));

    var userNameParameter = userName != null ?
        new ObjectParameter("UserName", userName) :
        new ObjectParameter("UserName", typeof(string));

    var exportParameter = export.HasValue ?
        new ObjectParameter("Export", export) :
        new ObjectParameter("Export", typeof(bool));

    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<CreatePrice_Result>("CreatePrice", typeParameter, codeParameter, userNameParameter, exportParameter);
}

返回类型如下:

public partial class CreatePrice_Result
{
    public string ActiveDate { get; set; }
    public string ActiveTime { get; set; }
    public string InactiveDate { get; set; }
    public string InactiveTime { get; set; }
}

这就是我的问题所在。如果“export”参数设置为true,则创建存储过程的DB Admin将返回结果集,如果“export”参数设置为false,则返回值0。生成的代码似乎不明白这一点。

如果我执行存储过程并将值设置为false。我收到这个错误:

  

System.Data.Entity.Core.EntityCommandExecutionException:数据读取器与指定的“CreatePrice_Result”不兼容。类型为“ActiveDate”的成员在数据读取器中没有相应的具有相同名称的列。

我想最简单的事情就是要求DB Admin修改存储过程以返回结果集而不管export的值如何但是这会破坏该参数的点,因为如果它被设置为false,我不会不需要它。

有没有办法让生成的代码能够处理这两种情况,即处理两种返回类型。此外,我试图避免生成的代码中的手动更改,因为它被覆盖。

我尝试将返回类型更改为object,并尝试根据“export”参数返回不同的结果

if (export == null || export == false)
{
   return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<int>("CreatePrice", typeParameter, codeParameter, userNameParameter, exportParameter);
}
else
{
   return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<CreatePrice_Result>("CreatePrice", typeParameter, codeParameter, userNameParameter, exportParameter);    
}

但是我收到了这个错误:

  

ExecuteFunction中的类型参数'System.Int32'与函数返回的类型'CreatePrice_Result'不兼容。

由于

1 个答案:

答案 0 :(得分:1)

我不相信如果不诉诸ADO.NET对象就可以做到。但是,您可以使用ObjectContext.Translate<TElement>方法将结果映射到实体对象,并可选择跟踪实体集中的结果。下面的演示代码:

SQL sproc:

create proc dbo.FuzzyResultSet
(
    @mode int
)
as

if( @mode = 1 )
begin
    -- execute non-query
    return @mode
end
else if( @mode = 2 )
begin
    -- execute scalar
    select @mode
end
else
begin
    -- execute reader
    select * from dbo.Watches
end

C#代码:

class Program
{
    static void Main( string[] args )
    {
        using( var db = new DBFirst.EFMREntities() )
        {
            db.Database.Initialize( force: false );

            try
            {
                db.Database.Connection.Open();

                var objContext = ( db as IObjectContextAdapter ).ObjectContext;

                // mode 0 returns a result set
                var reader = GetCmd( db, 0 ).ExecuteReader();
                var entityResults = objContext
                    .Translate<DBFirst.Watch>( reader, 
                        // next two parms only if you want results in an entity set
                        "Watches", MergeOption.OverwriteChanges );

                // mode 2 returns a scalar
                var scalarResult = GetCmd( db, 2 ).ExecuteScalar();

                // mode 1 does not return a result set
                var cmd = GetCmd( db, 1 );
                var nonQueryResult = cmd.ExecuteNonQuery();
                var nonQueryReturnParm = cmd.Parameters[ "@RETURN_VALUE" ];
                var nqrpValue = Convert.IsDBNull( nonQueryReturnParm.Value ) ? null : ( int? )nonQueryReturnParm.Value;

                Console.WriteLine( "Entities returned: {0}", entityResults.Count() );
                Console.WriteLine( "Scalar result: {0}", scalarResult );
                Console.WriteLine( "Non-query results: {0} / {1}", nonQueryResult, nqrpValue );
            }
            finally
            {
                db.Database.Connection.Close();
            }
        }

        Console.ReadLine();
    }

    private static DbCommand GetCmd( DbContext context, int value )
    {
        var cmd = context.Database.Connection.CreateCommand();

        var inParm = cmd.CreateParameter();
        inParm.ParameterName = "@mode";
        inParm.Value = value;

        var outParm = cmd.CreateParameter();
        outParm.ParameterName = "@RETURN_VALUE";
        outParm.Direction = ParameterDirection.ReturnValue;

        cmd.CommandText = "dbo.FuzzyResultSet";
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddRange( new []{ inParm, outParm } );

        return cmd;
    }
}