3

SQLite データベースを介して Entity Framework 4 モデルを使用しています。モデルの一部はこんな感じ ここに画像の説明を入力

すべての 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'.

更新: EF がエンティティの 1 つの識別子として実際に文字列を返す SQL クエリを生成することがわかりました。

DB に送信される 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

ここに画像の説明を入力

最後の列は証明書エンティティの ID です。しかし、最後のタイプは Guid で、前の文字列は - 文字列です。クエリの一部を個別に実行すると、次の列の型が取得されます (最後の 2 つから)。

  1. 最初の選択: ガイド、オブジェクト
  2. 2 番目の選択: オブジェクト、ガイド
  3. すべて結合: GUID、オブジェクト
  4. 外側の選択: 文字列、Guid

外部選択が最後から 2 番目の列で文字列を返すのはなぜですか?

4

2 に答える 2

0

順番がポイントのようです。順序付けを行わないと、最後の 2 つの列の結果の型は Guid と Objects になります。注文あり - 文字列とガイド。どちらの順序式も列に依存し[Extent2].[Id]ます。SQLite は Guid 型を操作しないので、値は String に変換されると思います。これは、EF4 と System.Data.SQLite の統合の難しさの 1 つです。だから私はEFが順序句を生成しないようにする方法を見つける必要があります...

于 2013-07-04T08:41:16.483 に答える
0

外部結合を実行すると、クエリで欠損値が検出されると、行CASE WHEN ([Extent2].[Id] IS NULL) THEN NULL ELSE 1 END AS [C1]は null 値を返します。C1.NET では、GUID は値型 (128 ビット整数) であるため、フープを介してジャンプしないと null に設定できません。( GUID 構造体の nullability の詳細については、Guid.IsNullOrEmpty() メソッドがない理由を参照してください。)

返される値は NULL 可能であり、xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx としてフォーマットされているため、文字列であると見なされます。

于 2013-07-03T23:14:35.690 に答える