我正在尝试使用Dapper简单地将我的数据库表映射到C#中的类型,但是,我的一些类型需要不在表中的其他元素.为此,我使用的工厂可以获取列值并设置适当的属性.
public IEnumerable<IMyType> All() {
var query = _connection.Query("SELECT * FROM [table]");
return query.Select(o => _myTypeFactory.Create(o));
}
Run Code Online (Sandbox Code Playgroud)
目前这导致return语句生成错误:
无法将表达式转换'System.Collections.Generic.IEnumerable<dynamic>'为返回类型'System.Collections.Generic.IEnumerable<IMyType>'
我的工厂类看起来像这样:
public class MyTypeFactory {
public IMyType Create(dynamic o) {
return Create((String) o.Code, (Int32) o.KeyID);
}
public IMyType Create(String code, Int32 keyID) {
return new MyType(code, Cache.Lookup(keyID));
}
}
Run Code Online (Sandbox Code Playgroud)
为什么Select()方法不返回IEnumerable<IMyType>?我需要做些什么来完成这项工作?这只是错误的做法,还有更好的方法吗?
最简单的解决方法就是使用Cast<>LINQ运算符:
public IEnumerable<IMyType> All() {
var query = _connection.Query("SELECT * FROM [table]");
return query.Select(o => _myTypeFactory.Create(o))
.Cast<IMyType>();
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以投射每个元素:
public IEnumerable<IMyType> All() {
var query = _connection.Query("SELECT * FROM [table]");
return query.Select(o => (IMyType) _myTypeFactory.Create(o));
}
Run Code Online (Sandbox Code Playgroud)
它目前不起作用,因为在IEnumerable<dynamic>和之间根本没有可用的隐式转换IEnumerable<IMyType>.IEnumerable<dynamic>可以通过多种方式实现,并且假设每个项目将动态生成,则没有理由假设结果值将实现IEnumerable<IMyType>.
我同意它看起来第二种形式实际上并没有添加任何东西,但是编译器没有检查所有可能的返回类型_myTypeFactory.Create(o)- 它将整个表达式视为动态值,即表达式是类型dynamic.因此Select结果仍然是类型IEnumerable<dynamic>.
另一种选择是指定泛型类型参数Select.
public IEnumerable<IMyType> All() {
var query = _connection.Query("SELECT * FROM [table]");
return query.Select<IMyType>(o => _myTypeFactory.Create(o));
}
Run Code Online (Sandbox Code Playgroud)
那是试图强制lambda表达式Func<dynamic, IMyType>- 我相信这将有效......
编辑:如注释中所述,强制在编译时解析方法调用也将修复它.基本上它取决于你发现最可读的东西.
| 归档时间: |
|
| 查看次数: |
3232 次 |
| 最近记录: |