设置EntityState.Unchanged后,实体属性将丢失 [英] After setting EntityState.Unchanged the entity properties are lost

查看:325
本文介绍了设置EntityState.Unchanged后,实体属性将丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ASP.Net MVC项目,我添加一个学生实体
到我的Entity Framework 6存储库。

  class Student 
public long Id {get;组; }
public virtual Book Favorite {get;组; }

class Book
public long Id {get;组; }
public string标题{get;组;

收藏夹属性设置为在视图中下拉。
在发布的控制器中,仅设置了该书的 Id
要告诉实体框架,只添加学生,但不添加
参考书,我将该书的EntityState设置为不变为
描述这里



保存更改后,我在数据库中还有正确的学生记录,还有书记录保持不变,但
每当我从我的存储库(而不是通过学生)查询这本书时,我会收到一个书实体
,其中只有设置Id,标题和所有其他属性都为空。



我的控制器(简化):

  public ActionResult Create() 
{
StudentViewModel result = new StudentViewModel();
result.BookList = new SelectList(DbContext.Books,Id,Name);
return View(result);
}

[HttpPost]
public ActionResult Create(StudentViewModel viewModel)
{
DbContext.Entry(viewModel.NewStudent.Favorite).State = EntityState .UnChanged);
DbContext.Add(viewModel.NewStudent);
DbContext.SaveChanges();

Book missingProperties =
DbContext.Books.Single(book => book.Id == viewModel.NewStudent.Favorite.Id);
}

我的观点(简体):

  @using System.Linq 
@model StudentViewModel
@using(Html.BeginForm())
{
..
@ Html.TextBoxFor(model => model.NewStudent.Name)
@ Html.DropDownListFor(model => model.NewStudent.Favorite.Id,Model.BookList)

}


解决方案

问题是,实体框架DbContext缓存实体。


使用懒惰加载,您只需要参考相关数据,实体框架将检查是否已加载到内存中。如果没有,实体框架将在后台创建并执行查询,填充相关数据。



默认情况下,Visual Studio将定义新创建的模型以将LazyLoadingEnabled设置为


(来自 MSDN



从db加载后,DbContext生命周期将不再加载。
EntityState.UnChanged 只能将实体框架存储回数据库。但是,无论何时从上下文中检索实体,而不是从数据库中获取正确的值,而是修改,现在也在缓存中。



还需要刷新修改后的实体。将其附加在DbContext中,然后重新加载。

 书籍结果=附加(书); 
条目(book).Reload();

我想,这回答了问题,但我不知道GuruStron的答案是否使用更好的模式。


I have an ASP.Net MVC project where I add in a View a student entity to my Entity Framework 6 repository.

class Student
  public long Id { get; set; }
  public virtual Book Favorite { get; set; }

class Book
  public long Id { get; set; }
  public string Title { get; set; }

The Favorite property is set from a drop down in the view. In the controller on post, only the Id for the book is set. To tell Entity Framework, to only add the student, but not to add the referenced book, I set the EntityState for the Book to Unchanged as described here

After saving my changes, I have the correct student record in the database and also the book record remains unchanged, but whenever I query now the book from my repository (not via the student), I get a book entity back where only the Id is set and Title and all other properties are null.

My Controller (simplified):

public ActionResult Create()
{
    StudentViewModel result = new StudentViewModel();
    result.BookList = new SelectList(DbContext.Books, "Id", "Name");
    return View(result);
}

[HttpPost]
public ActionResult Create(StudentViewModel viewModel)
{
    DbContext.Entry(viewModel.NewStudent.Favorite).State = EntityState.UnChanged);
    DbContext.Add(viewModel.NewStudent);
    DbContext.SaveChanges();

    Book missingProperties = 
        DbContext.Books.Single(book => book.Id == viewModel.NewStudent.Favorite.Id);
} 

My View (simplified):

@using System.Linq
@model StudentViewModel
@using (Html.BeginForm())
{        
    ...
    @Html.TextBoxFor(model => model.NewStudent.Name)
    @Html.DropDownListFor(model => model.NewStudent.Favorite.Id, Model.BookList)
    ...
}

解决方案

The problem is, that the Entity Framwork DbContext caches entities.

With lazy loading, you simply need to make some reference to the related data and the Entity Framework will check to see whether it’s been loaded into memory. If not, the Entity Framework will create and execute a query behind the scenes, populating the related data.

By default, Visual Studio will define newly created models to set LazyLoadingEnabled to true.

(from MSDN)

Once loaded from db, it will not be loaded again for the DbContext lifetime. EntityState.UnChanged prevents Entity Framework only from storing the entity back to the database. But whenever the entity is retrieved from context a second time, not the correct value from database is taken, but the modified, that is now also in cache.

It is additionally necessary to refresh the modified entity. Attach it in the DbContext and then reload it.

Book result = Attach(book);
Entry(book).Reload();

I think, this answers the issue, but I am not sure if GuruStron answer uses the better pattern.

这篇关于设置EntityState.Unchanged后,实体属性将丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆