3

私はこの問題についてかなりの時間を探していました。

これが取引です。Web API を呼び出してデータを取得する Web サイトを構築しています。私の Web API はライブラリを使用し、リポジトリ パターンを操作します。私のデータベース モデル (EF モデル ファースト) は、ライブラリで構築されました。そのモデルには、基本クラスのパスがあります。次に、CustomerCard : Pass と Voucher : Pass という 2 つの派生クラスがあります。EF Designer からの私のモデル

すべての CustomerCards を取得するメソッドがあります。

public IQueryable<CustomerCard> GetAllPasses() {
        IList<CustomerCard> allCards = new List<CustomerCard>();

        var c_cards = context.Passes;
        foreach (var c_card in c_cards) {
            if (c_card is CustomerCard) {
                allCards.Add((CustomerCard)c_card);
            }
        }
        return allCards.AsQueryable<CustomerCard>();
    }

私の ApiController では、次のように、このメソッドを使用してパスを取得し、それらを Web サイトに返します。

    [HttpGet]
    [Queryable]
    public IQueryable<CustomerCard> GetAllPasses(string version) {
        return passRepo.GetAllPasses().AsQueryable();
    }

私の Web API は JSON 形式を返します。これは、参照などを保持するための私の構成です。

        var json = config.Formatters.JsonFormatter;
        json.SerializerSettings.PreserveReferencesHandling =
            Newtonsoft.Json.PreserveReferencesHandling.Objects;
        json.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
        config.Formatters.Remove(config.Formatters.XmlFormatter);

Web サイトのデータをページングできるようにするため、IQueryable を使用しています。API メソッドは「/api/v1/passes/all」で利用できます。

ここが奇妙な部分です。ページングをテストするために、ページごとに 1 つのパスを呼び出します。私の最初のパスでは、問題なく動作します。しかし、2 番目のページに移動すると、彼も正しいパスを取得しますが、User への参照はなくなります。

私のモデルでわかるように、CustomerCard クラスには User プロパティがあります。これは、顧客カードの所有者を示します。

したがって、この呼び出しはパスからユーザーをロードします: 'api/v1/passes/all?$top=1' しかし、これを呼び出すと、ユーザー インスタンスはNULLです: 'api/v1/passes/all?$top= 1&$skip=1'.

ただし、「api/v1/passes/all?$top=2」を呼び出すと、2 番目のパスのユーザーが読み込まれます。だから、これは私の心が吹き飛ばされるところです!理解できません?ユーザー参照が2番目のものと一緒に来ないのはなぜですか? EF の遅延読み込み機能と何か関係があるのでしょうか?

編集 context.passes で拡張メソッド Include を使用すると、エラーがスローされます。

指定されたインクルード パスが無効です。EntityType 'LCS_Model.Pass' は、'User' という名前のナビゲーション プロパティを宣言していません。

これは、パスが dbset として渡され、CustomerCard と Voucher が含まれているためです。コンテキストに期待するか、CustomerCard に変換するように指示する方法はありますか?

誰か助けてください。私の質問が理解できない場合は、質問してください。

もうありがとう!

編集2

APIコントローラーのメソッドは現在

[HttpGet]
[Queryable]
public IQueryable<CustomerCard> GetAllPasses(string version) {
     return context.Passes.Include("User").OfType<CustomerCard>();
}

これで正しいアイテムが得られます。私のデータベースには2枚の顧客カードがあります。どちらも同じユーザーからのものです。私のAPIにはまだユーザーがロードされています。Web サイトが応答を受信した瞬間、User プロパティが null になります。私の推測では、配列の最初の要素から同じユーザーを参照しているためです。それは可能ですか?はいの場合、どうすればそれを防ぐことができますか?

4

1 に答える 1