2013-06-28 4 views
3

У меня есть модель Entity Framework 4 по SQLite databese. Часть модели выглядит так: enter image description hereОшибка материализации LINQ to Entity

Все поля Id имеют тип Guid (уникальный идентификатор в SQLite-таблице DDL). Но когда я запускаю следующий запрос LINQ, я получаю исключение.

var query = AbonentPfrs.Select(a => 
    new 
    { 
     AbPfr = a, 
     Pfr = a.PfrCertificates.Select(c => c.Id), 
     Ac = a.AcCertificates.Select(c => c.Id) 
    } 
); 
query.ToList(); 

Когда я запускаю его я получаю

System.InvalidOperationException: The type of the key field 'Id' is expected to be 'System.Guid', but the value provided is actually of type 'System.String'. 

UPDATE: я узнал, что EF генерировать SQL запрос, который действительно возвращает строки в качестве идентификаторов для одного из субъектов.

SQL, который идет к БД ((query as ObjectQuery).ToTraceString()) выглядит следующим образом:

SELECT 
[UnionAll1].[C2] AS [C1], 
[UnionAll1].[C3] AS [C2], 
[UnionAll1].[Id] AS [C3], 
[UnionAll1].[PfrRegNumber] AS [C4], 
[UnionAll1].[PfrUnitId] AS [C5], 
[UnionAll1].[Account_Id] AS [C6], 
[UnionAll1].[ActiveCertificate_Id] AS [C7], 
[UnionAll1].[C1] AS [C8], 
[UnionAll1].[Id1] AS [C9], 
[UnionAll1].[C4] AS [C10] 
FROM (SELECT 
    CASE WHEN ([Extent2].[Id] IS NULL) THEN NULL ELSE 1 END AS [C1], 
    1 AS [C2], 
    1 AS [C3], 
    [Extent1].[Id] AS [Id], 
    [Extent1].[PfrRegNumber] AS [PfrRegNumber], 
    [Extent1].[PfrUnitId] AS [PfrUnitId], 
    [Extent1].[Account_Id] AS [Account_Id], 
    [Extent1].[ActiveCertificate_Id] AS [ActiveCertificate_Id], 
    [Extent2].[Id] AS [Id1], 
    NULL AS [C4] 
    FROM [AbonentPfrs] AS [Extent1] 
    LEFT OUTER JOIN [Certificates] AS [Extent2] ON [Extent1].[Id] = [Extent2].[AbonentPfr_PfrCertificates_Certificate_Id] 
UNION ALL 
    SELECT 
    2 AS [C1], 
    2 AS [C2], 
    2 AS [C3], 
    [Extent3].[Id] AS [Id], 
    [Extent3].[PfrRegNumber] AS [PfrRegNumber], 
    [Extent3].[PfrUnitId] AS [PfrUnitId], 
    [Extent3].[Account_Id] AS [Account_Id], 
    [Extent3].[ActiveCertificate_Id] AS [ActiveCertificate_Id], 
    NULL AS [C4], 
    [Extent4].[Id] AS [Id1] 
    FROM [AbonentPfrs] AS [Extent3] 
    INNER JOIN [Certificates] AS [Extent4] ON [Extent3].[Id] = [Extent4].[AbonentPfr_AcCertificates_Certificate_Id]) AS [UnionAll1] 
ORDER BY [UnionAll1].[Id] ASC, [UnionAll1].[C1] ASC 

enter image description here

Последние столбцы идентификаторы для субъектов сертификации. Но последние имеют тип Guid и предыдущую строку. Если я запускаю части запроса отдельно, то я типа следующий столбец (FOT двух последних):

  1. Сначала выберите: Guid, объект
  2. Второй выбор: Объект, Guid
  3. Союза все: Guid, объект
  4. Outer выберите: String, Guid

Почему внешние выберите возвращает строки в предпоследнем столбце?

+0

Я думаю, что это потому, что две связи в одной таблице - от AbonentPfr до сертификатов. Но я не уверен ... – sedovav

+0

Возможно, потому что SQLite хранит GUID как строки? AFAIK SQLite не имеет собственного типа данных GUID. – okrumnow

+0

, но во всех других запросах он работает корректно – sedovav

ответ

0

Кажется, что заказ - это пункт. Без упорядочения результатов в последних двух столбцах находятся Guid и Objects. С заказом - String и Guid. Оба выражения порядка зависят от столбца [Extent2].[Id]. SQLite не использует тип Guid, поэтому, я думаю, значения преобразуются в String. Это одна из трудностей интеграции EF4 и System.Data.SQLite. Поэтому мне нужно найти способ заставить EF не генерировать предложение упорядочения ...

0

При выполнении внешнего соединения строка CASE WHEN ([Extent2].[Id] IS NULL) THEN NULL ELSE 1 END AS [C1] вернет нулевое значение для C1, когда ваш запрос встречает отсутствующее значение. В .NET GUID - это тип значения (128-битное целое число), поэтому его нельзя установить равным нулю, не перескакивая через обручи. (см. Why isn't there a Guid.IsNullOrEmpty() method для получения дополнительной информации о недействительности структуры GUID.)

Поскольку возвращаемое значение является нулевым и отформатировано как xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, оно считается строкой.

+0

Я изменил изображение результата, чтобы показать, какие столбцы типа имеют. Как видите, проблема заключается в столбце «C9», который является объединением '[Extent2]. [Id]' и 'NULL'. Но столбец «C10» хорош - тип результата - Guid. И я не вижу разницы. C10 является результатом объединения 'NULL' и' [Extent4]. [Id] '. Необходимо сказать, что оба '[Extent2]. [Id]' и '[Extent4]. [Id]' имеют одинаковый тип db. – sedovav