私はこの問題についてかなりの時間を探していました。
これが取引です。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 になります。私の推測では、配列の最初の要素から同じユーザーを参照しているためです。それは可能ですか?はいの場合、どうすればそれを防ぐことができますか?