【问题标题】:Entity Framework: Storing Entities without saving to Database实体框架:存储实体而不保存到数据库
【发布时间】:2011-05-10 13:06:38
【问题描述】:

如何在ObjectContext中存储临时项而不保存到数据库?

Context存储在HttpContext中,按类提供:

public static class HttpContextExtension
{
    public static MyEntityDataModelContainer GetMyContext(this HttpContext httpContext)
    {
        if (httpContext.Items["MyEntityDataModelContainer"] == null)
        {
            httpContext.Items.Add("MyEntityDataModelContainer", new MyEntityDataModelContainer());
        }

        return (MyEntityDataModelContainer)httpContext.Items["MyEntityDataModelContainer"];
    }
}

有两个空白页面: 1)FirstPage.aspx.cs:

public class FirstPage : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // crete new item
        MyEntity newTemporaryItem = new MyEntity { MyEntityID = Guid.NewGuid() };
        // attach them to Context
        HttpContext.Current.GetMyContext().MyEntitySet.Attach(newTemporaryItem);
        // save changes
        HttpContext.Current.GetMyContext().SaveChanges();

        // get all attached to Context items
        var addedItems = (from se in HttpContext.Current.GetMyContext().ObjectStateManager.GetObjectStateEntries(EntityState.Unchanged)
                          where se.Entity is MyEntity
                          select se.Entity).AsQueryable();
        int CountInFirstPage = addedItems.Count();
    }
}

所以,CountInFirstPage = 1。

2) SecondPage.aspx.cs:

public class FirstPage : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // get added in First page items From HttpContext
        var addedItems = (from se in HttpContext.Current.GetMyContext().ObjectStateManager.GetObjectStateEntries(EntityState.Unchanged)
                          where se.Entity is MyEntity
                          select se.Entity).AsQueryable();
        int CountInSecondPage = addedItems.Count();
    }
}

这里CountInSecondPage = 0。

我哪里错了?

【问题讨论】:

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


    【解决方案1】:

    我说第二页是第二个请求对吗?

    在这种情况下,您有一个新的 HttpContext.Items 集合,并且您上次请求的值已经消失。在这种情况下考虑使用会话来存储这些值。

    脚注: EntityContext 应该只用于一个请求,因此可以存储在 HttpContext.Items 集合中,但不能作为 Session 值!只在此处存储计数结果。

    【讨论】:

    • 是的,SecondPage 通过链接从 FirstPage 定位...正在尝试使用 Session
    • 有效!我通过 httpContext.Session 重新制作了 HttpContextExtension。谢谢!
    • 这不是什么新鲜事,我只需要引用@BrokenGlass 但是即使可以以这种方式存储数据库上下文,即即使您决定将其存储在会话中 - 这是不是要走的路 - 每个上下文的范围应该是一个工作单元,你不应该让它长时间保持活动状态,尤其是在 Web 环境中。 保持你的 EntityContext 真的很糟糕活在 WebEnvironment 中。您应该始终删除它,只存储您以后可能需要的结果。这条评论有很多缺点。
    • 在为每个请求设置新的 EntityContext 时,您不会损失太多性能。在您的示例中,您只需要下一个请求中的计数。您还可以将该值作为 GET 参数存储在链接中,从而使您从会话中解放出来。这样,它们将在下一个视图中可用。在我看来,这将是您的案例最干净的解决方案。该值恰好存储在您需要的位置。无论只有一个还是数百个
    • Julie Lerman 有一本关于 EntityFramework 4 的非常好的书,您应该阅读它。
    【解决方案2】:

    这是错误的方法,HttpContext 仅具有单个 HTTP 请求的范围,因此您在第二个请求中处理不同的上下文。

    但是,即使可以以这种方式存储 DB 上下文,即即使您决定将其存储在 Session 中 - 这不是要走的路 - 每个上下文的范围应该是单个工作单元,您不应该让它长时间保持活动状态,尤其是在 Web 环境中。

    只需将您的临时项目直接保存在 Session 中,并创建一个新的上下文以在您准备好时上传这些项目。

    【讨论】:

    • -1 会话对于实体框架对象来说是一个糟糕的解决方案。 EF 仅根据需要进行枚举,因此任何子对象都不会存在,并且当您调用 EF 的保存更改方法时,它将失败。
    • 据我所知,类实例只是一个没有其他依赖项且不附加到上下文的实体类,因此就像您可以在会话中保存任何其他类实例一样,您应该能够对这个做同样的事情。我不太明白你的担心。
    • 他需要在第二页的查询中检索更改的对象,我将假设数据绑定到控件。
    • @Chad 是的,我将使用该值将其绑定到第二页中的 ComboBox。一种可能的方法是在页面之间通过 Session 传递值并将接收到的值附加到 Context,对吧?
    • @BrokenGlass 我在您的帖子中没有发现任何问题。不知道乍得是什么意思。因此+1
    【解决方案3】:

    为了使用 EF 对新数据运行查询,您需要保存。您可以列出然后对列表运行查询,但这需要您将列表保存在某种静态内存(会话状态、视图状态、缓存)中,但如果列表很大,可能会产生其他问题。

    您可以在TRANSACTION 中做任何事情。传递事务直到您提交或回滚。实体对象被保存,但当事务回滚时,任何更改都将撤消。我认为事务将通过回发和重定向持续存在,但需要在呈现页面时提交或处置。

    【讨论】:

    • 您的意思是“传递事务”== 在页面之间传递吗?我认为它只适用于一个 EntityContext...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多