LINQ options.loadwith 问题
我正在编写一个基于标签的 ASP.net 系统。 使用以下数据库方案:
主题
,这是我从以下内容中找到的 3NF 方法(toxi):http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html
这是我的代码片段:
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Topic>(t => t.TagTopicMaps);
options.LoadWith<TagTopicMap>(tt => tt.Tag);
var db = new lcDbDataContext();
db.LoadOptions = options;
db.Log = w;
var x = from topic in db.Topics
orderby topic.dateAdded descending
select topic;
ViewData["TopicList"] = x.Take(10);
当我执行此操作时,结果很好,但它出现了 11 个单个 SQL 查询,其中一个用于获取前 10 个主题的列表:
SELECT TOP (10) [t0].[Id], [t0].[title], [t0].[dateAdded]
FROM [dbo].[Topics] AS [t0] ORDER BY [t0].[dateAdded] DESC
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1
另外 10 个用于单独获取标签的详细信息。
我尝试打开和关闭两个 loadwith 语句,发现发生了以下情况:
loadwith<topic> : no difference for on or off.
loadwith<tagtopicmap>: 11 Queries when on, much more when off.
简而言之,只有第二个 loadwith 选项按预期工作。 第一个没有任何效果!
我还尝试将结果集设为ToList()。 但更多的问题出现了:对于标签详细信息部分,它只检索那些唯一的项目,所有这些重复标签(当然,相同的标签可能出现在多个主题中!)都会被查询删除。
最后一件事,以下是我在 aspx 中用于检索数据的代码,为了使结果为 list(),我将 (IQueryable) 更改为 (IList):
<% foreach (var t in (IQueryable)ViewData["TopicList"])
{
var topic = (Topic)t;
%>
<li>
<%=topic.title %> ||
<% foreach (var tt in (topic.TagTopicMaps))
{ %>
<%=tt.Tag.Name%>,
<%} %>
</li>
<%
}
%>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
简短的答案是:LinqToSql 有几个像这样的怪癖,有时您必须使用解决方法...
Linq2Sql LoadWith 选项只会导致数据库表之间的内部联接,因此您可以通过将 Linq 语句重写为像这样的东西(请原谅任何拼写错误,我习惯用 VB 语法编写 Linq...):
这种语法可能非常错误,但基本思想是强制 Linq2Sql 评估 Topics 和 TagTopicMaps 之间的连接,然后使用分组(或“group join”、“let”等)来保留结果集中的对象层次结构。
The short answer is: LinqToSql has several quirks like this, and sometimes you have to use work-arounds...
The Linq2Sql LoadWith option simply causes an inner join between the database tables, so you can force similar behavior by rewritting your Linq statement to something like (please forgive any typos, I'm used to writting Linq in VB syntax...):
This syntax may be horribly wrong, but the basic idea is that you force Linq2Sql to evaluate the join between Topics and TagTopicMaps, and then use grouping (or "group join", "let", etc.) to preserve the object heirarchy in the result set.
将数据上下文类上的 EnabledDefferedLoad 设置为 false。
Set the EnabledDefferedLoad on your datacontext class to false.
您的情况的问题是 Take(10)。 以下来自马口:
https://connect.microsoft.com/VisualStudio/feedback/details/473333/linq-to-sql-loadoptions-ignored-when-using-take-in-the-query
建议的解决方法是添加 Skip(0)。 这对我不起作用,但 Skip(1) 确实有效。 虽然可能没什么用,但至少我知道我的问题出在哪里。
The problem in your case is Take(10). Here's from the horse's mouth:
https://connect.microsoft.com/VisualStudio/feedback/details/473333/linq-to-sql-loadoptions-ignored-when-using-take-in-the-query
The suggested workaround is to add Skip(0). That did not work for me, but Skip(1) did work. Useless as it may be, at least I know where my problem is.