1

私たちのデータベースには、データベース ファースト EF モデルのエンティティにマップした次のようなテーブルがあります。

CREATE TABLE Texts(
  Id integer,
  Eng nvarchar(max),
  Nob nvarchar(max),
  ...
)

このテーブルの行は非常に大きい可能性があるため、ユーザーが行った言語選択によって現在必要とされている列の値のみを取得したいと考えています。

私の考えは、私のためにそれを行うための拡張機能を持つことでしたが、それを書く方法がわかりませんし、見つけることもできません(可能であれば)。いくつかのバリエーションを試してみましたが、(明らかに) store 式に変換できないという例外で失敗しました。だから私は少し立ち往生しています。

この関数の使用法は次のとおりです。

context.Codes.Where(row => row.Id == 234).Select(row => new {
  row.Id,
  Text = Text.GetLocalizedText("Eng") // This should generate an SQL that only retrieves the Eng 
                                      // column of the Text navigation property (which is 
                                      // connected to the Texts table.
});

これにより、次のような選択が生成されます (Text.Eng を直接使用することを除いて、上記の例と同様です)。

SELECT 
[Extent1].[Id] AS [Id], 
[Extent2].[Eng] AS [Eng]
FROM  [dbo].[Codes] AS [Extent1]
INNER JOIN [dbo].[Texts] AS [Extent2] ON [Extent1].[TextId] = [Extent2].[Id]
WHERE 234 = [Extent1].[Id]

これが可能かどうか、また可能かどうかは誰にもわかりません。どのように書くのですか?それが不可能な場合、すべての列を含む Text エンティティ全体を取得せずにこれを解決する方法について、他に考えがある人はいますか?

4

1 に答える 1

0

の拡張メソッドは機能IQueryable<Code>しますが、実行するプロジェクションのタイプごとに拡張が必要であり、匿名の結果オブジェクトを操作できないため、必要なほど柔軟ではありません。

アイデアは基本的に次のようになります。

投影できる名前付きクラス (匿名ではなく) が必要です。

public class CodeData
{
    public int Id { get; set; }
    public string LocalizedText { get; set; }
}

そして、language パラメーターを持つ拡張メソッド:

public static class CustomExtensions
{
    public static IQueryable<CodeData> SelectCodeData(
        this IQueryable<Code> query, string language)
    {
        switch (language)
        {
            case "Eng":
                return query.Select(code => new CodeData
                {
                    Id = code.Id,
                    LocalizedText = code.Text.Eng
                });

            case "Nob":
                return query.Select(code => new CodeData
                {
                    Id = code.Id,
                    LocalizedText = code.Text.Nob
                });
            //... more languages
        }

        throw new ArgumentException("Invalid language code.", "language");
    }
}

次に、次のように呼び出すことができます。

using CustomExtensions;

// ...

IQueryable<CodeData> codeDataQuery = context.Codes
    .Where(row => row.Id == 234)
    .SelectCodeData("Eng");
于 2013-03-30T15:26:52.407 に答える