重新制定问题:
如何让代理解决部分加载的关节而不重新加载所有子关联?
上下文:
我有两个实体:
新闻的
+ Id:int
+日期:日期时间NewsTranslation
+ NewsId:id(实体News.Id的外键)
+ LanguageCode:char(2)
+标题:nvarchar(255)
+内容:nvarchar(2000)
一个新闻可以包含 NewsTranslation (每个LanguageCode一个)
例如,这里是数据库中的数据:
News {
Id: 1,
Date: "01/01/2015"
Translations : [
{ NewsId: 1, LanguageCode: "en", Title: "Title", Contents: "English contents" },
{ NewsId: 1, LanguageCode: "fr", Title: "Titre", Contents: "French contents" }
]
}
我想加载新闻实体,但仅限于当前的语言翻译(例如英语" en")。
我的代码:
News entity = null;
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
using(var context = new MyContext())
{
// Disabling lazyloading (see why at the bottom of the code)
context.Configuration.LazyLoadingEnabled = false;
// Load News with inner join NewsTranslation to retrieve
// only english language "en"
entity = (from news in context.News
select new {
News = news,
NewsTranslation = from trans in news.NewsTranslation
where trans.NewsId == news.Id
&& trans.LanguageCode == "en"
select trans
}).First()
}
//
// Serialize traverse all properties and associations.
//
// WITHOUT above "context.Configuration.LazyLoadingEnabled = false;" it would
// lazy load all associations NewsTranslation. Additionaly, the Context is closed so
// an exception is thrown
//
serializer.Serialize(entity)
这段代码运作正常,但我很害怕这样做......
在不禁用LazyLoading配置的情况下,这是更好的方法吗?
更新
基于 Brian Mains 建议:
翻译第一种方法:
News entity = null;
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
using(var context = new MyContext())
{
entity = (from trans in context.NewsTranslation
where trans.LanguageCode == "en"
select trans.News).First();
}
//
// The proxy try to lazy load News.NewsTransation association,
// so an exception is thrown beacause the Context is closed
//
//
serializer.Serialize(entity)
同样的问题,如何让代理解决部分加载的关节?
答案 0 :(得分:0)
我有两种方式可以看到;您可以使用let关键字查询当前转换(在sql中呈现子查询)。请参阅另一个SO示例:Using the "let" kewword in a LINQ Query with EF 4.3
或者,首先查询翻译,然后包含新闻项,然后构建模型:
var data = from trans in news.NewsTranslation.Include("News")
where trans.LanguageCode == "en"
select trans;
数据变量包含NewsTranslation对象,带有预加载的News属性;如果您想要的只是新闻,那么您可以将查询更改为:
var data = from trans in news.NewsTranslation
where trans.LanguageCode == "en"
select trans.News;
我不确定这会产生什么样的LINQ,是否是一个简单的连接;您可以随时加入新闻实体并直接选择,而不是使用新闻对象。
编辑:如果您只想要第一个对象,只需执行:
var results = (from trans in context.NewsTranslation
where trans.LanguageCode == "en"
select trans.News).First();
请勿使用ToList()
且不要使用Select()
;它没有给你任何东西。