ASP.NET C#EF - 如何在选择完整对象后使其受益?

时间:2012-09-13 11:04:09

标签: c# asp.net entity-framework-4

我一直在使用Entity Framework开发ASP.NET C#,有些人对某些关键点非常有帮助。

还有一点我无法完全理解。当我们从EF中检索数据时,我们不应该使用对象及其子对象(外键关系表数据)吗?

这是我的数据库设计(也在我之前回答的问题中显示) enter image description here

在我的代码中,我只是得到这样的成员实体:

//In some aspx.cs file
var Mem = new MemberManager().GetById(2);

//In MemberManager class
public Member GetById(long id)
        {
            using(var Context = new NoxonEntities())
            {
                return Context.Member.First(c => c.Id == id);
            }
        }

当我这样做时:

var Mem = new MemberManager().GetById(2);
var Lang = Mem.Language;
//I get 
//Error: 'Mem.Language' threw an exception of type 'System.ObjectDisposedException'

为了摆脱这种异常,我需要这样做:

public Member GetById(long id)
        {
            using(var Context = new NoxonEntities())
            {
                var Result = Context.Member.First(c => c.Id == id);
                //Getting the Language Entity
                Result.Language = Context.Language.First(c => c.Id == Result.LanguageId);

                return Result;
            }
        }

我是否必须运行SELECT才能拥有 FULL 实体?如果有另一个相关表到语言表,请说功能表。我应该这样做:

public Member GetById(long id)
            {
                using(var Context = new NoxonEntities())
                {
                    var Result = Context.Member.First(c => c.Id == id);
                    //Getting the Language Entity
                    Result.Language = Context.Language.First(c => c.Id == Result.LanguageId);
                    Result.Language.Feature = Context.Language.Feature.First(c => c.Id == Result.FeatureId);
                    return Result;
                }
            }

这可能会很长时间 我很确定(至少我真的希望)我错了什么,但如果我们不能使用该对象及其子对象 AFTER 选择,那么拥有EF的目的是什么?我们是否只能在using(var Context = new NoxonEntities())块中使用子对象?

谢谢,

2 个答案:

答案 0 :(得分:3)

将上下文视为数据库连接。在using语句中创建上下文并在using末尾将其丢弃时,可以使用此连接。 using块之后的所有内容都无法再访问数据库连接。你在这里得到例外......

var Lang = Mem.Language;

...因为延迟加载尝试从数据库加载Language导航属性,但是已经处理了与数据库的连接。当与数据库的连接仍然可用时,您只能在<{em> 块中使用这种延迟加载。

您可以使用预先加载 using来简化加载示例中的导航属性:

Include

或两种导航属性都使用:

public Member GetById(long id)
{
    using(var Context = new NoxonEntities())
    {
        return Context.Member.Include("Language").First(c => c.Id == id);
    }
}

它将在单个数据库查询中加载成员语言和功能。

答案 1 :(得分:2)

您的问题是由于延迟加载造成的。发生的事情是EF没有加载您的相关实体Language,因为它不确定它是否需要数据。然后,您正在处理上下文,因此当您尝试访问Language导航属性时,它无法进行跳转。

这里有几个选项。你可以急切加载,这是一个非常棒的blog post,渴望加载,语言实体:

var Result = Context.Member.Include("Language").First(c => c.Id == id);

或者,您需要在整个请求中保持上下文的活动状态。这是一个good post on a great method to keeping your context alive for each request

我确实记得你是其他帖子 - 而且我相信你正在分离你的实体并将其存储在其他地方,然后重新附加。如果这与该功能相关,那么访问您的语言对象, 后将其附加到上下文也将解决您的问题。