我很想知道是否有其他人遇到过同样的问题......
我在项目的ORM上使用Dapper,并且创建了一些我自己的扩展方法 IDbConnection
界面为了简化代码,我遇到了(我发现的)令人费解的错误。
我将介绍我经历的过程。
首先,我在一个名为的静态类中为我的项目添加了一个扩展方法 DbExtensions
像这样:
using System.Collections.Generic;
using System.Data;
using System.Linq;
public static class DbExtensions
{
public static T Scalar<T>(
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
{
var ret = cnn.Query<T>(sql, param as object, transaction, buffered, commandTimeout, commandType).First();
return ret;
}
}
这会使用以下描述创建编译错误:
'System.Data.IDbConnection' has no applicable method named 'Query' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.
这很好,错误实际上很有帮助,因为它甚至告诉我如何解决它。所以我尝试:
using System.Collections.Generic;
using System.Data;
using System.Linq;
public static class DbExtensions
{
public static T Scalar<T>(
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
{
var ret = SqlMapper.Query<T>(cnn, sql, param, transaction, buffered, commandTimeout, commandType).First();
return ret;
}
}
它正确编译。虽然有些奇怪的事情发生了。在Visual Studio中,如果我取回的值 SqlMapper.Query<T>
哪一个 应该 是 IEnumerable<T>
,我尝试对它进行操作,Visual Studio给我没有intellisense属性,除了那些继承通过 object
。
以为我只是在做一些智能感知不够聪明的事情,我继续我的快乐方式......直到我真的尝试运行代码。
当我尝试运行它时,它会在我呼叫的地方绊倒 .First()
出现以下错误:
'System.Collections.Generic.List<MyNameSpace.MyClass>' does not contain a definition for 'First'
现在这个错误,我觉得很有意思......在敲了一下头之后,我意识到第一个论点是抱怨动态打字......
我想这个错误正在发生,因为编译器无法构建通用模板,因为它不知道Query正在返回 IEnumerable<T>
因为它正在DLR中执行?我很想听到有人解释这个知识渊博的人。我基本上找到了两种方法来解决它:
- 投了
dynamic
param to aobject
- 将返回的值转换为
IEnumerable<T>
using System.Collections.Generic;
using System.Data;
using System.Linq;
public static class DbExtensions
{
public static T Scalar<T>(
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
{
var ret = SqlMapper.Query<T>(cnn, sql, param as object, transaction, buffered, commandTimeout, commandType).First();
return ret;
}
}
using System.Collections.Generic;
using System.Data;
using System.Linq;
public static class DbExtensions
{
public static T Scalar2<T>(
this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
{
var ret = ((IEnumerable<T>)SqlMapper.Query<T>(cnn, sql, param, transaction, commandTimeout, commandType)).First();
return ret;
}
}
综上所述:
我是新手,通过DLR的qwerks,在搞乱动态+泛型时,似乎需要记住一些注意事项......?
我知道这不是一个问题本身,但当我真正开始写这篇文章时,我不知道发生了什么,我在这个过程中想出来了!我认为它可能会帮助其他有类似问题的人...