我有一个带有Entity Framework 4模型的WCF服务,使用序列化并发送到客户端应用程序的POCO类。我将LazyLoadingEnabled
和ProxyCreationEnabled
设置为false
,我正在使用Linq来实现查询实体,并通过List<>
将其返回给客户端。当我不使用Include()时,一切都很完美:
public List<TBLTable1> GetTBLTable1(string pCode)
{
using (PcFactoryEntities oPcFactoryDB = new PcFactoryEntities())
{
oPcFactoryDB.ContextOptions.ProxyCreationEnabled = false;
oPcFactoryDB.ContextOptions.LazyLoadingEnabled = false;
var oRS = oPcFactoryDB.TBLTable1
.Where(c => c.Code == pCode).ToList();
XmlObjectSerializer serializer = new DataContractSerializer(typeof(TBLTable1));
serializer.WriteObject(new XmlTextWriter(Console.Out) { Formatting = Formatting.Indented }, oRS[0]);
return oRS;
}
}
在Linq查询之后,我使用序列化程序来模拟将POCO类发送到客户端时发生的序列化过程,并且我工作得很好。但是,当我添加一个Include()来加载该类的一个导航列表时,它开始序列化所有Table2
的导航列表,就好像LazyLoadingEnabled被设置为true一样,并且它会继续序列化,可能是整个数据库!
public List<TBLTable1> GetTBLTable1(string pCode)
{
using (PcFactoryEntities oPcFactoryDB = new PcFactoryEntities())
{
oPcFactoryDB.ContextOptions.ProxyCreationEnabled = false;
oPcFactoryDB.ContextOptions.LazyLoadingEnabled = false;
var oRS = oPcFactoryDB.TBLTable1
.Include("TBLTable2")
.Where(c => c.Code == pCode).ToList();
XmlObjectSerializer serializer = new DataContractSerializer(typeof(TBLTable1));
serializer.WriteObject(new XmlTextWriter(Console.Out) { Formatting = Formatting.Indented }, oRS[0]);
return oRS;
}
}
为什么会这样?不应将LazyLoadingEnabled设置为false应用于手动包含的类,并将其所有导航列表返回null
,因为它与Table1
的所有其他导航列表一样?有没有办法解决这个问题所以我可以使用Table1返回一些导航列表,其导航列表设置为null
?
TKS
答案 0 :(得分:2)
尝试投影到DTO并对其进行序列化,而不是尝试直接序列化实体。我同意你看到的是奇怪的行为 - 但是当你序列化实体时,EF内部图可能会接管,但是如果你序列化DTO,EF就不应该介入。
E.g:
var dto = oPcFactoryDB.TBLTable1
.Where(x => x.Code == pCode)
.Select(x => new SpecialisedDTO
{
PropertyOne = x,
PropertyTwo = x.TBLTable2
}).ToList();
然后序列化。
自投射以来,您不需要急切加载 - EF会根据您提供的查询获取所需内容。
在N-Tier情况下,通过线路传输DTO通常是很好的做法,而不是纯粹的POCO实体。
答案 1 :(得分:0)
您是否在TBLtable1到TBLtable2上有导航属性? .Include()用于包含与FK关系链接的实体,并且.Include()传递导航属性的名称。
因此,如果您有一个具有NavigationProperty的Person Entity到名为PersonAddresses的地址实体,那么您将执行以下操作以获取Person及其地址。
var p = dbContext.Person
.Where(x => x.Id == id)
.Include("PersonAddresses")
.SelectFirstOrDefault;