我已经在这个问题上寻找了相当长的时间。
事情是这样的。我正在构建一个网站,调用Web API来获取数据。我的Web API使用库,并使用存储库模式。我的数据库模型(EF Model-first)是在库中构建的。在那个模型中,我有一个基类Pass。然后我有两个派生类:CustomerCard:Pass和Voucher:Pass。我的 EF Designer 模型
我有一个方法来获取所有的顾客卡。
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”处获得。
奇怪的是,为了测试我的分页,我每页调用一个pass。 对于第一个Pass,它正常工作。但是当我转到第二页时,它也获取了正确的pass,但User的引用消失了。
如您在我的模型中所看到的,CustomerCard类具有用户属性。这表示谁拥有客户卡。
因此,此调用从pass加载用户:'api/v1/passes/all?$top=1' 但是当我调用这个时,用户实例是NULL: 'api/v1/passes/all?$top=1&$skip=1'。
然而,当我调用“api/v1/passes/all?$top=2”时,第二个pass的User被加载。 所以这就是我不理解的地方!我不明白?为什么第二个pass的用户引用没有出现?这可能与EF的惰性加载功能有关吗?
编辑 当我在context.passes上使用Include扩展方法时,会抛出错误:
指定的包含路径无效。实体类型'LCS_Model.Pass' 没有声明名为'User'的导航属性。
这是因为Passes作为一个dbset,包含CustomerCard以及Voucher。有没有办法告诉我的上下文去期望或将其转换为CustomerCard?
能否有人帮助我。如果您不明白我的问题,请随时提问!
感谢您的帮助!
编辑2
我的API控制器上的方法现在是:
[HttpGet]
[Queryable]
public IQueryable<CustomerCard> GetAllPasses(string version) {
return context.Passes.Include("User").OfType<CustomerCard>();
}
这使我得到了正确的项目。我的数据库中有2张客户卡,它们都来自同一个用户。我的API仍然加载着这个用户。当我的网站接收到响应时,用户属性变为null。我猜测这是因为它仍在引用数组的第一元素中相同的用户。这可能吗?如果是,我该如何防止发生这种情况?