我想从下面的linq查询中获取IEnumerable。我做错了什么?
IEnumerable<DataRow> results =
context.Database.SqlQuery<DataRow>("SELECT * FROM Customer").AsEnumerable();
答案 0 :(得分:3)
DataRow
类没有默认(无参数)构造函数,因此您不能将其用作查询参数类型。类型参数没有通用约束,MSDN(!)上没有提及,但如果参数类型没有默认构造函数,列映射工厂将抛出异常:
结果类型'System.Data.DataRow'可能不是抽象的,必须 包括默认构造函数。
这是抛出此异常的代码:
internal static CollectionColumnMap CreateColumnMapFromReaderAndClrType(
DbDataReader reader, Type type, MetadataWorkspace workspace)
{
BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
ConstructorInfo constructor = type.GetConstructor(flags, (Binder) null, Type.EmptyTypes, (ParameterModifier[]) null);
if (type.IsAbstract || (ConstructorInfo) null == constructor && !type.IsValueType)
throw EntityUtil.InvalidOperation(InvalidTypeForStoreQuery((object) type));
// ...
}
BTW 映射到DataRow是没有意义的,即使它有默认的公共构造函数。因为它不是简单的基本类型,并且它没有与查询返回的列名相匹配的属性(是的,映射仅使用属性)。
正确使用Linq
IEnumerable<Customer> results = context.Customers;
这将生成SELECT * FROM Customer
查询,并将查询结果映射到客户实体。如果你真的想使用原始SQL:
IEnumerable<Customer> results =
context.Database.SqlQuery<Customer>("SELECT * FROM Customers");
答案 1 :(得分:0)
我认为我们正试图解决同样的问题(无论如何,Google引领我到这里)。我正在通过SqlQuery<TElement>(string sql, params object[] parameters
执行原始SQL命令,并希望在单元测试中断言从查询返回的结果的各个属性。
我打电话给方法:
var result = (db.SqlQuery<Customer>("select * from customers").First();
并验证了它返回的数据:
Assert.AreEqual("John", result.FirstName);
我在我的测试类中定义了一个私有类Customer
(不幸的是,我没有使用实体框架):
private class Customer
{
public string FirstName { get; set; }
}
Customer的属性必须与SQL查询中返回的列名匹配,并且它们必须是属性(而不仅仅是Customer
类的变量。您不必为所有的属性创建属性从查询返回的列。