我有一个遗留存储过程(我无法改变)。它返回一个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?
答案 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;
}