I’m trying to use Dapper simply to map my database tables to types in C#, however, some of my types need additional elements that are not in the table. To do this I am using a factory that can take column values and set the appropriate properties.
public IEnumerable<IMyType> All() {
var query = _connection.Query("SELECT * FROM [table]");
return query.Select(o => _myTypeFactory.Create(o));
}
Currently this is resulting the return statement generating an error:
Cannot convert expression type 'System.Collections.Generic.IEnumerable<dynamic>' to return type 'System.Collections.Generic.IEnumerable<IMyType>'
My factory class looks something like this:
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));
}
}
Why doesn’t the Select() method return IEnumerable<IMyType>? What do I need to do to make this work? Is this just the wrong approach and there’s a better way?
The simplest fix is just to use the
Cast<>LINQ operator:Alternatively, you could cast each element:
It doesn’t currently work because there’s simply no implicit conversion available between
IEnumerable<dynamic>andIEnumerable<IMyType>.IEnumerable<dynamic>could be implemented in any number of ways, and given that each item will be generated dynamically there’s no reason to suppose the result value will implementIEnumerable<IMyType>.I agree that it looks like the second form isn’t actually adding anything, but the compiler doesn’t check all the possible return types of
_myTypeFactory.Create(o)– it treats that whole expression as a dynamic value, i.e. the expression is of typedynamic. Therefore theSelectresult is still of typeIEnumerable<dynamic>.Another option is to specify the generic type argument to
Select.That’s attempting to force the lambda expression to a
Func<dynamic, IMyType>– I believe that will work…EDIT: As noted in comments, forcing the method invocation to be resolved at compile-time will fix it too. Basically it depends what you find most readable.