2

我正在尝试从下面的 linq 查询中获取 IEnumerable。我究竟做错了什么?

IEnumerable<DataRow> results = 
    context.Database.SqlQuery<DataRow>("SELECT * FROM Customer").AsEnumerable();
4

2 回答 2

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");
于 2013-10-02T22:42:58.643 回答
0

我认为我们正在尝试解决同样的问题(无论如何,谷歌把我带到了这里)。我正在执行一个原始 SQL 命令,SqlQuery<TElement>(string sql, params object[] parameters并希望在单元测试中断言从查询返回的结果的各个属性。

我调用了这个方法:

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类的变量。您不必为查询返回的所有列创建属性。

于 2014-03-12T02:26:11.793 回答