我在VS 2010中使用EF 3.5。我有一个返回结构的方法。在结构中有一个对象armatuur。返回结构时,我想从armatuur实例访问相关对象。
然而
返回struct的方法:
public LampPostDetail getLamppostInfo(int id)
{
LampPostDetail lpd;
lpd.xPos = 0;
lpd.ypos = 0;
lpd.armatuur = new Armatuur();
//get the info from object
using (var db = new OvisionDBEntities())
{
var objects = from o in db.Objects
where o.ObjectId == id
select o;
foreach (OVSL.Data.Object o in objects)
{
lpd.xPos = o.XCoordinatie;
lpd.ypos = o.YCoordinatie;
lpd.armatuur = o.Armatuur; //which is a table in my db
}
return lpd;
}
}
结构:
public struct LampPostDetail
{
#region [ Data Members (14)]
//lamppost info
public double? xPos;
public double? ypos;
//a lamppost can have several armaturen
public OVSL.Data.Armatuur armatuur; //is a table in my db
#endregion [ Data Members ]
}
在我的客户端执行此操作时:
LampPostDetail lpd = client.getLamppostInfo(id);
string brand = lpd.armatuur.producer.name; //producer is related object of armatuur
我得到一个ObjectDisposedException。我知道这是因为LampPostDetail对象在使用块完成后被释放。但我如何让这个工作?在我将其返回给客户之前,检索我需要的所有信息(例如品牌名称)不是一种选择。
答案 0 :(得分:0)
它不是你正在处理的LampPostDetail,它是你从它引用的数据库中检索到的Armatuur对象,或者是Armatuur引用的对象。
我可以看到两种方法来解决这个问题。第一种方法是将Entity上下文作为getLamppostInfo info方法的可选参数。由于您使用的是3.5,因此必须执行重载以保持原始功能:
public LampPostDetail getLamppostInfo(int id,OvisionDBEntities context)
{
...
try
{
OvisionDBEntities db;
if (context == null)
db = new OvisionDBEntities();
else
db = context;
...
}
finally
{
if (context == null && db != null)
db.Dispose() // or close maybe
}
retun lpd;
}
// Overloaded function to keep orignal functionality (C# 3.5 does not have
// optional parameters)
public LampPostDetail getLamppostInfo(int id)
{
return LampPostDetail(id,null)
}
现在您可以将其命名为:
using (var db = new OvisionDBEntities())
{
LampPostDetail lpd = client.getLamppostInfo(id,db);
string brand = lpd.armatuur.producer.name;
}
当您尝试引用它们时,您的对象仍然存在。
另一种选择是在处理之前将引用的对象与实体上下文分离。
db.Detach(o.Armatuur);
但是,我不相信分离该对象的任何对象引用。所以你必须对参考树进行交互并分离对象。
答案 1 :(得分:0)
这里唯一要处理的是OvisionDBEntities
上下文。之后,不可能进行延迟加载。怎么处理?实际上,您的问题是:您可以做些什么来随时向用户提供用户操作可能需要的所有数据?我看到三个或四个选项:
在上下文处理后启用对实体导航属性的访问的标准方法是调用Include:from o in db.Objects.Include("Armatuur.Producer")...
但这显然不适合您。
让上下文生效并依赖延迟加载来按需获取数据。这可能是您的选择。但是,随着内部变更跟踪记录的增长,长期存在的上下文可能会导致性能逐渐下降等问题,并且过时的缓存数据会导致刷新/重新加载语句遍布整个地方。
代替导航属性/延迟加载从服务/存储库层按需获取数据,该服务/存储库层使用每个调用的上下文实例。我认为这个选项适合你。
更多功能而不是技术选项:设计可以使用较少数据的用例(这样Include
可能就足够了)。没有人可以接纳数千行和数十列的网格。精心设计的用户交互可以大大减少泵入客户端的数据量(仅在开始时才开始)。