LINQ options.loadwith问题
我正在编写一个基于标签的ASP.net系统。 使用以下数据库方案:
Topic TagTopicMap Tag
基本上,我从以下方面找到了3NF方法(toxi): http ://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html
这是我的代码片段:
DataLoadOptions options = new DataLoadOptions(); options.LoadWith(t => t.TagTopicMaps); options.LoadWith(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 : no difference for on or off. loadwith: 11 Queries when on, much more when off.
简而言之,只有第二个loadwith选项按预期工作。 第一个没有任何效果!
我还尝试制作结果集ToList()。 但是更多的问题出现了:对于标签细节部分,它只检索那些唯一的项目,所有那些重复的标签(当然,相同的标签可能出现在许多主题中!)被查询删除。
最后一件事,以下是我在aspx中用来检索数据的代码,如果使结果为tolist(),我将(IQueryable)更改为(IList):
|| ,
简短的回答是:LinqToSql有这样的几个怪癖,有时你必须使用解决方法……
Linq2Sql LoadWith选项只会导致数据库表之间的内部联接,因此您可以通过将Linq语句重写为类似的方式来强制执行类似的行为(请原谅任何拼写错误,我习惯用VB语法编写Linq …):
var x = from topic in db.Topics join topicMap in topic.TagTopicMaps orderby topic.dateAdded descending group topicMap by topicMap.topic into tags = Group;
这种语法可能是非常错误的,但基本的想法是你强迫Linq2Sql评估Topics和TagTopicMaps之间的连接,然后使用分组(或“group join”,“let”等)来保留对象层次结构。结果集。
将datacontext类上的EnabledDefferedLoad设置为false。
您的问题是Take(10)。 这是马的嘴巴:
建议的解决方法是添加Skip(0)。 这对我不起作用,但Skip(1)确实有效。 尽管它可能没用,至少我知道我的问题在哪里。