我有这两个班:
public class BusinessesTBL { public string ID { get; set; } public string FirstName { get; set; } public string lastName { get; set; } public ICollection<OffersTBL> OffersTBLs { get; set; } } public class OffersTBL { public int ID { get; set; } public string Name { get; set; } public int CatId { get; set; } public string BusinessesTBLID { get; set; } public virtual BusinessesTBL BusinessesTBLs { get; set; } }
当我尝试根据CatId字段提供所有优惠时,我还需要返回BusinessesTBLs,但是该方法也会再次为每个BusinessesTBL obj返回优惠,我的代码是:
public IQueryable<OffersTBL> GetOffersTBLsCat(int id) { db.OffersTBLs.Include(s => s.BusinessesTBLs); }
你可以看到错误的结果:
http://priooffer.azurewebsites.net/api/OffersApi/GetOffersTBLsCat/4
您可以看到它返回每个业务对象下的所有优惠,而在每个提供下的业务对象,我只想在Business obj下返回没有提供的业务对象的优惠。
请问有人帮忙吗?
解决方法
这是因为实体框架执行关系修正,这是在上下文中存在属于该对象的对象时自动填充导航属性的过程。所以通过循环引用,您可以无缝地向下钻取导航属性,即使禁用惰性加载。 Json serializer完全是这样(但是显然它被指示来处理循环引用,所以它不会陷入无止境循环)。
诀窍是防止关系修复从以前的打击。关系修补依赖于上下文的ChangeTracker,该缓存缓存对象跟踪其更改和关联。但是如果没有什么可追踪的话,没有什么可以解决的。您可以通过调用AsNoTracking()来停止跟踪:
db.OffersTBLs.Include(s => s.BusinessesTBLs) .AsNoTracking()
除此之外,您还可以禁用上下文中的延迟加载(通过设置contextConfiguration.LazyLoadingEnabled = false),您将看到只有OffersTBL.BusinessesTBLs填充在Json字符串中,并且BusinessesTBL.OffersTBLs是空数组。
一个好处是,AsNoTracking()会提高性能,因为更改跟踪器不是跟踪EF实现的所有对象。实际上,您应该始终在断开连接的设置中使用它。