Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在实体框架中使用语句完成后,如何访问相关对象?_C#_Entity Framework - Fatal编程技术网

C# 在实体框架中使用语句完成后,如何访问相关对象?

C# 在实体框架中使用语句完成后,如何访问相关对象?,c#,entity-framework,C#,Entity Framework,我在VS 2010中使用了EF 3.5。我有一个返回结构的方法。在结构中有一个对象armatuur。当返回结构时,我希望从armatuur实例访问相关对象 然而 返回结构的方法: public LampPostDetail getLamppostInfo(int id) { LampPostDetail lpd; lpd.xPos = 0; lpd.ypos = 0; lpd.armatuur = new Armatuur(); //get the i

我在VS 2010中使用了EF 3.5。我有一个返回结构的方法。在结构中有一个对象armatuur。当返回结构时,我希望从armatuur实例访问相关对象

然而

返回结构的方法:

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对象是在使用块完成后处理的。但是我怎样才能让它工作呢?在我将信息返回给客户之前,检索我需要的所有信息(例如品牌名称)不是一个选项。

处理的不是您的LampPostDetail,而是您从数据库检索到的Armatuur对象,或者Armatuur正在引用的对象

我可以看到两种解决方法。第一个是将实体上下文作为getLamppostInfo方法的可选参数。由于您使用的是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); 

但是,我不相信这会通过该对象分离任何对象引用。因此,您必须交互引用树并分离这些对象。

这里唯一要处理的是
OvisionDBEntities
上下文。之后,就不可能进行延迟加载。如何处理?事实上,您的问题是:您可以做什么来随时向客户机提供用户操作可能需要的所有数据?我看到三到四个选择:

  • 在上下文处理之后,允许访问实体导航属性的标准方法是调用:
    从db.Objects.Include(“Armatuur.Producer”)…
    ,但这显然不是您的选项

  • 让上下文处于活动状态,并依靠延迟加载按需获取数据。这可能是您的一个选择。但长期存在的上下文可能会导致一些问题,如随着内部更改跟踪记录的增长,性能逐渐下降,过时的缓存数据会导致分散在各地的刷新/重新加载语句

  • 代替导航属性/延迟加载,从每次调用都使用上下文实例的服务/存储库层按需获取数据。我认为这个选择对你来说很合适

  • 与其说是一个技术选项,不如说是一个功能选项:设计可以使用较少数据的用例(这样
    Include
    就足够了)。没有人能接受一个包含数千行和数十列的网格。精心设计的用户交互可以大大减少输入到客户端的数据量(我只是刚刚开始了解这一点)


  • 抛出异常的具体行是什么?我知道这是在你的客户机中,但很难准确判断哪一行是问题所在。你有能力修改getLamppostInfo方法吗?@yyy,这是询问制作人的行。是的,我可以编辑该方法。@user957902只是ping你,因为OP在ping我的同时回答了你的问题。啊!格式怎么了?我所有的缩进都不见了!好的,谢谢你的时间,我明天会在工作中试用,我会让你知道的!选项4要求对代码进行最少的更改,这是我们的目标。UI设计确实应该专注于开发;)