使用 WCF 序列化 Entity Framework 4 POCO 类时使用 Include() 时出现问题
我有一个带有 Entity Framework 4 模型的 WCF 服务,使用 POCO 类进行序列化并发送到客户端应用程序。我将 LazyLoadingEnabled
和 ProxyCreationEnabled
设置为 false
,并且我使用 Linq to Entites 查询实体,并通过 返回它向客户端列出<>
。当我不使用 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
?
塔克斯
I have a WCF service with an Entity Framework 4 model, using POCO classes that are serialized and sent over to client applications. I have LazyLoadingEnabled
and ProxyCreationEnabled
set to false
, and I'm using Linq to Entites to query an Entity, and return it via List<>
to the client. Everything goes perfect when I don't use 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;
}
}
After the Linq query, I use the serializer to simulate the serialization process that happens when the POCO class is sent to the client, and I works great. However, when I add an Include() to load one of the navigation list for the class, it starts serializing all of Table2
's navigation's list as if LazyLoadingEnabled was set to true, and it goes on forever serializing probably the whole database!
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;
}
}
Why is this happening? Shouldn't the LazyLoadingEnabled set to false apply to the class included manually and return all of it's navigation lists to null
as it happens with all of the other navigation lists for Table1
? Is there a way to fix this so I can return with Table1 some navigations lists filled in with their navigation lists set to null
?
Tks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不要尝试直接序列化实体,而是尝试投影到 DTO 并序列化它。我同意您所看到的奇怪行为 - 但可能是 EF 内部图在您序列化实体时接管,但如果您序列化 DTO,EF 不应干预。
例如:
然后将其序列化。
由于您的投影,您不需要急切加载 - EF 将根据您提供的查询获取所需的内容。
在 N 层情况下,通过线路传输 DTO,而不是纯粹的 POCO 实体,通常是一种很好的做法。
Instead of trying to directly serialize the entity, try projecting to a DTO and serializing that. I agree what your seeing is bizarre behaviour - but it could be that the EF internal graph is taking over when your serializing the entities, but if you serialize a DTO, EF should not intervene.
E.g:
And then serialize that.
Since your projecting, you don't need to eager load - EF will grab what it needs to based on the query you have provided.
It's usually good practice in N-Tier situations to transmit DTO's over the wire, rather than the pure POCO entities.
您在 TBLtable1 到 TBLtable2 上有导航属性吗? .Include() 用于包含通过 FK 关系链接的实体,并且 .Include() 传递导航属性的名称。
因此,如果您有一个 Person 实体,该实体具有指向名为 PersonAddresses 的地址实体的 NavigationProperty,那么您将执行以下命令以获取该 Person 及其地址。
Do you have a Navigation Property on TBLtable1 to TBLtable2? The .Include() is used to include entities that are linked va FK relationships and the .Include() is passed the Name of the Navigation Property.
So if you have a Person Entity with a NavigationProperty to an Addresses Entity called PersonAddresses you would then execute the following in order to get the Person and their addresses.