从ExecuteMethodCall()获取一个枚举

时间:2015-04-17 21:39:21

标签: c# linq-to-sql enums

我有一个遗留存储过程(我无法改变)。它返回一个int,并声明Linq2Sql方法返回一个int(如此)工作正常:

public int spExample_upd(
    [Parameter(Name = "Id1", DbType = "int")] int id1,
    [Parameter(Name = "Id2", DbType = "int")] int id2)
{
    IExecuteResult result = ExecuteMethodCall(this, (MethodInfo)MethodInfo.GetCurrentMethod(), id1, id2);
    return (int)result.ReturnValue;
}

sproc只返回一组有限的结果,只有0,1和-1。我没有返回int(在我的C#代码中),而是希望spExample_upd()返回一个枚举:

public enum DbReturn
{
    Success = 0,
    Failure = 1,
    NoCountOn = -1
}

当我声明spExample_upd()返回DbReturn时:

public DbReturn spExample_upd(
    [Parameter(Name = "Id1", DbType = "int")] int id1,
    [Parameter(Name = "Id2", DbType = "int")] int id2)
{
    IExecuteResult result = ExecuteMethodCall(this, (MethodInfo)MethodInfo.GetCurrentMethod(), id1, id2);
    return (DbReturn)result.ReturnValue;
}

...我得到了运行时错误" DbReturn不是映射存储过程方法的有效返回类型。"当调用ExecuteMethodCall()时会发生这种情况,因此我甚至无法取回结果然后尝试将其强制转换。

我尝试通过将spExample_upd()更改为强制/强制方法信息的返回类型:

[return: Parameter(DbType = "Int")]
[ResultType(typeof(int))]
public DbReturn spExample_upd(
    [Parameter(Name = "Id1", DbType = "int")] int id1,
    [Parameter(Name = "Id2", DbType = "int")] int id2)
{
    IExecuteResult result = ExecuteMethodCall(this, (MethodInfo)MethodInfo.GetCurrentMethod(), id1, id2);
    return (DbReturn)result.ReturnValue;
}

...但是这没有任何结果(我仍然遇到运行时错误)。

是否可以调用ExecuteMethodCall,获取从sproc返回的int,将其转换为DbReturn,然后让spExample_upd()返回DbReturn?

1 个答案:

答案 0 :(得分:1)

问题是由MethodInfo.GetCurrentMethod()调用之间的冲突引起的,该调用创建表示当前方法的签名的MethodInfo实例(包括返回类型)和验证返回的ExecuteMethodCall()调用。该签名的价值是合适的。当您更改方法的返回类型时,ExecuteMethodCall()内的验证会检测到签名不合适并产生您看到的错误。

您可以通过使用枚举公开的API和使用整数的内部API来解决问题,但这几乎与Rahul在评论中提到的一样。理想情况下,您可以在某处隐藏来自客户端API的数据库特定位,而DataContext可能不是最佳位置,尽管下面的解决方法可以解决。

public DbReturn spExample_upd(int id1)
{
    return (DbReturn)spExample_upd_internal(id1);
}

[Function(Name = "spExample_upd")]
private int spExample_upd_internal([Parameter(Name = "Id1", DbType = "int")] int id1)
{
    var result = ExecuteMethodCall(this, (MethodInfo)MethodInfo.GetCurrentMethod(), id1);
    return (int)result.ReturnValue;
}