1

因此,我正在开发一个将实体存储在 Session 变量中的现有应用程序,并且每次回发都尝试将其重新附加到新的上下文中。我并不特别关心这个实现,但现在重写它是不可能的。代码看起来像这样:

public partial class ReviewDetail
{
    DBContext context = new DBContext();

    public void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            int id = Convert.ToInt32(Request.QueryString["id"]);
            Session["Review"] = context.Reviews.FirstOrDefault(x => x.ReviewID = id);
        }
        else
        {
            Review review = Session["Review"] as Review;
            context.Attach(review);
        }
    }
}

这适用于初始页面加载和第一次回发。但是,在随后的回发中,它失败并出现以下错误:

具有临时 EntityKey 值的对象不能附加到对象上下文。

奇怪的是(对我来说,无论如何)是当我在 VS 调试器中单步执行代码并检查 review.EntityKey 的属性时,IsTemporary 字段为假。

关于我应该如何解决这个问题的任何建议?我试过调用 .AttachTo("Reviews", review) 但我最终遇到了同样的错误。

到目前为止,我认为我知道的是,当我进行第一个 .Attach 调用时,它附加了“review”对象,但由于它是一个引用对象,它也修改了 Session 中的对象并向它添加了一个 EntityKey(我可能在这里我的术语或我的理解不正确——这对我来说是 EF 中的一个薄弱环节)。所以现在,在第一次回发之后,我的 Session 对象已经被“附加”了。第二次(当它失败时),它已经被附加了,所以它失败了?

我认为我在正确的轨道上,只是不确定如何从这里进行修复。理想情况下,我们不会这样做,但除非没有其他选择,否则可能不会在这里使用更正确的方法重写它。

任何建议表示赞赏。

编辑:我应该在有人回答之前提到这一点,但我无法在每次回发时返回数据库以获取评论。会话中的对象稍后会被修改,它的数据可能与数据库中的数据不同。

4

2 回答 2

2

我会从您的会话变量中获取实体,并使用它的 ID 属性重新查询上下文,例如:

public partial class ReviewDetail
{
    DBContext context = new DBContext();

    public void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            int id = Convert.ToInt32(Request.QueryString["id"]);
            Session["Review"] = context.Reviews.FirstOrDefault(x => x.ReviewID = id);
        }
        else
        {
            Review review = Session["Review"] as Review;

            Review updateReviewFromContext = context.ApplyCurrentValues<Review>("Reviews", review);         
        }
    }
}

这是一个简单的更改,并且您将整个对象存储在会话中有点无关紧要,但是如果您无法更改,这应该可以为您解决问题。

更新

请参阅:http: //msdn.microsoft.com/en-us/library/dd487246

ApplyCurrentValues将从会话中获取您的更新Review并将其更新的属性应用于从上下文返回的实体。唯一的诀窍是你必须知道它EntitySetName是什么,在我的例子中是“评论”,但只要这不会改变它就可以被硬编码。

于 2012-06-11T18:40:33.837 回答
1

这些问题通常是实体框架在附加对象时如何工作的结果。附加实体时,您将递归附加它引用的每个实体。例外情况具有误导性,因为我们自然会假设错误出在我们显式附加的实体上,而在许多情况下,问题出在隐式附加的实体上。

因此,我不确定您的代码片段的缩写程度,但您似乎正在尝试附加一个引用新创建实体的实体。

于 2012-06-11T19:09:22.257 回答