2013-10-02 4 views
1

Я пытаюсь получить IEnumerable из запроса linq ниже. Что я делаю не так?Невозможно сопоставить необработанный SQL-запрос с DataRow

IEnumerable<DataRow> results = 
    context.Database.SqlQuery<DataRow>("SELECT * FROM Customer").AsEnumerable(); 
+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 Mapping в DataRow не имеет никакого смысла, даже если он будет иметь по умолчанию открытый конструктор. Поскольку это не простой примитивный тип и он не имеет свойств, которые соответствуют именам столбцов, возвращаемых из запроса (да, отображение использует свойства только).

Правильное использование Linq будет

IEnumerable<Customer> results = context.Customers; 

Это будет генерировать SELECT * FROM Customer запрос и отображение результатов запроса к лицам заказчика. Если вы действительно хотите использовать сырой SQL:

IEnumerable<Customer> results = 
    context.Database.SqlQuery<Customer>("SELECT * FROM Customers"); 
0

Я думаю, что мы пытались решить ту же задачу (Google привел меня сюда, в любом случае). Я выполняю необработанную команду SQL через SqlQuery<TElement>(string sql, params object[] parameters и хотел утверждать отдельные свойства результатов, возвращаемых из запроса в модульном тесте.

я назвал метод:

var result = (db.SqlQuery<Customer>("select * from customers").First(); 

и проверить данные, которые он возвращаемый:

Assert.AreEqual("John", result.FirstName); 

я определил частный класс Customer внутри моего тестового класса (к сожалению, я не использую Entity Framework):

private class Customer 
{ 
    public string FirstName { get; set; } 
} 

Свойства Клиента должны соответствовать имена столбцов, возвращаемые в SQL-запросе, и они должны быть свойствами (а не только переменными класса Customer. Вам не нужно создавать свойства для всех столбцов, возвращаемых из запроса.

Смежные вопросы