我一直在寻找相当长的时间来解决这个问题。
这是交易。我正在构建一个调用 Web API 以获取其数据的网站。我的 Web API 使用一个库,使用存储库模式。我的数据库模型(EF 模型优先)是在库中构建的。在那个模型中,我有一个基类 Pass。然后我有两个派生类,CustomerCard:Pass 和 Voucher:Pass。我的 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 中,我使用此方法获取通行证并将其返回到网站,如下所示:
[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);
我使用 IQueryable 是因为我希望能够在我的网站上对数据进行分页。api 方法在“/api/v1/passes/all”中可用。
这是奇怪的部分。为了测试我的分页,我每页调用 1 pass。对于我的第一个通行证,它工作正常。但是当我转到我的第二页时,他也得到了正确的通行证,但是对 User 的引用消失了。
正如您在我的模型中看到的,CustomerCard 类有一个属性 User。这表明谁拥有客户卡。
所以这个调用从 pass 加载用户:'api/v1/passes/all?$top=1' 但是当我调用这个时,用户实例是NULL:'api/v1/passes/all?$top= 1&$skip=1'。
但是,当我调用 'api/v1/passes/all?$top=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 仍然加载了用户。我的网站收到响应的那一刻,用户属性变为空。我的猜测是这是因为它仍然从数组的第一个元素引用同一个用户。那可能吗?如果是,我该如何防止这种情况发生?