我花了两天的时间来反对这个问题,我似乎无法破解它(问题是)。在添加数据库关系之前,相同的代码工作正常,之后我读了一个关于延迟加载的 lot 。
我有两个数据库表,它们之间有1:1的关系。 PromoCode
表跟踪代码,并有一个名为id
的PK列。 CustomerPromo
表格中有一列PromoId
,该列与PromoCode
表id
相关联。这两个表没有其他关系。我在SQL Server Management Studio中生成了所有这些,然后从数据库生成模型。
为了使事情稍微复杂一点,我在WCF数据服务中这样做,但我不相信应该有所作为(它在添加数据库关系之前有效)。启用日志记录后,我总是在日志文件中使用text:
获取Exception在Dispose之后访问DataContext。
我的函数当前返回表中的所有条目:
using (MsSqlDataContext db = new MsSqlDataContext())
{
// This causes issues with lazy-loading
return db.PromoCodes.ToArray();
}
我已阅读了大量文章/页面/答案,他们都说要使用.Include()
方法。但这对我不起作用:
return db.PromoCodes.Include(x => x.CustomerPromos).ToArray();
我已经尝试了#34;魔术字符串"版本:
return db.PromoCodes.Include("CustomerPromos").ToArray();
我设法开始工作的唯一代码是:
PromoCode[] toReturn = db.PromoCodes.ToArray();
foreach (var p in toReturn)
p.CustomerPromos.Load();
return toReturn;
我已尝试在查询中添加了.Where()
条件,我已尝试.Select()
,我已尝试在{.Include()
之后移动.Where()
1}}(this answer说要做到最后,但我认为这仅仅是由于嵌套查询)。我已经阅读了有关.Include()
will silently fail的情况,毕竟我已经没有了。
我错过了什么?语法问题?逻辑问题?一旦我得到这个"简单"如果工作正常,我还需要嵌套Include
s(即如果CustomerPromo
表与Customer
有关系)。
修改
包括所有相关代码。其余的是LINQ to SQL或WCF数据服务配置。这就是:
[WebGet]
[OperationContract]
public PromoCode[] Test()
{
using (MsSqlDataContext db = new MsSqlDataContext())
{
return db.PromoCodes.Include(x => x.CustomerPromos).ToArray();
}
}
如果我通过浏览器直接调用它(例如http://<address>:<port>/DataService.svc/Test
),我会收到重置连接消息,并且必须查找WCF日志以找出&#34; DataContext accessed after Dispose.
&#34;。如果我通过网页中的AJAX调用进行相同的查询,我会收到状态为error
的AJAX错误(这就是全部!)。
答案 0 :(得分:6)
当我实际上没有要获取的子数据时,我过早地发布了上一个答案。当时我只对获取父数据感兴趣,that answer工作。
现在当我真正需要子数据的时候,我发现它并没有完全发挥作用。我发现this article表示.Include()
(他说Including()
但我不确定这是否是拼写错误)已被删除,正确的解决方案是使用DataLoadOptions
。此外,我还需要enable Unidirectional Serialisation。
最重要的是,我不再需要DeferredLoadingEnabled
。所以现在最终的代码看起来像这样:
using (MsSqlDataContext db = new MsSqlDataContext())
{
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<PromoCode>(p => p.CustomerPromos);
db.LoadOptions = options;
return db.PromoCodes.ToArray();
}
设置Unidirectional Serialisation
后,它将很乐意返回父对象,而无需加载子项,或明确设置DeferredLoadingEnabled = false;
。
答案 1 :(得分:1)
编辑: 这并没有完全解决问题。在测试时,没有任何子数据,我也没有尝试使用它。这只允许我返回父对象,它不会返回子对象。有关完整解决方案,请参阅this answer。
与我读过的所有内容相反,答案不是使用.Include()
而是更改上下文选项。
using (MsSqlDataContext db = new MsSqlDataContext())
{
db.DeferredLoadingEnabled = false; // THIS makes all the difference
return db.PromoCodes.ToArray();
}
This link在问题评论中发帖(感谢@Virgil)提示答案。但是,我无法找到一种方法来访问LINQ to SQL的LazyLoadingEnabled
(我怀疑它是针对EntityFramework的)。 This page表明LINQ to SQL的解决方案是DeferredLoadingEnabled
。
以下是DeferredLoadingEnabled上的MSDN文档的链接。