奇怪的实体框架的行为 - 缓存?(Strange Entity Framework behaviou

2019-10-17 14:41发布

我一直在使用EF 4.3迁移ASP.NET MVC 4 appliation。 我使用的WebGrid助手来显示系统用户的详细信息:

@grid.GetHtml(
headerStyle: "gridHeader",
footerStyle: "gridFooter",
firstText: "<< First",
previousText: "< Previous", 
nextText: "Next >",
lastText: "Last >>",
alternatingRowStyle: "gridAlternativeRow",
columns: new[] {
   grid.Column("Login", header: "User Login", canSort: true),
   grid.Column("FullName", header: "User Name", canSort: true),
   grid.Column("Email", header: "User Email", canSort: true),
   grid.Column("Category", header: "User Category", canSort: true),
   grid.Column(
    "", 
    header: "", 
    format: @<text>
            @Html.ActionLink("Edit",   "Edit",   new { id=item.Id} )
            </text>
    )                                                
})

正如你所看到的编辑操作方法负责编辑用户详细信息。 这是如何通过视图模型到视图:

    public ActionResult Edit(int Id)
    {
        User user = repo.GetUser(Id);

        RegisterModel rm = new RegisterModel();
        rm.Id = user.Id;
        rm.Name = user.FullName;
        rm.UserName = user.Login;
        rm.Email = user.Email;
        rm.UserCategory = user.Category;
        rm.Categories = new List<SelectListItem>();

        List<Category> categories = repo.GetAllCategories();
        foreach (var item in categories)
        {
            SelectListItem sli = new SelectListItem();
            sli.Value = null;
            sli.Text = item.Title;
            if (user.Category == item.Title) sli.Selected = true;
            rm.Categories.Add(sli);
        }

        return View(rm);
    }

这是它是如何保存的详细信息:

    [HttpPost]
    public ActionResult Edit(RegisterModel rm, string NewPassword, string OldLogin)
    {
        if (NewPassword != "")
        {
            var token = WebSecurity.GeneratePasswordResetToken(OldLogin);
            WebSecurity.ResetPassword(token, NewPassword);
        }

        User user = new User();
        user.Id = Convert.ToInt32(rm.Id);
        user.FullName = rm.Name;
        user.Email = rm.Email;
        user.Category = rm.UserCategory;
        user.Login = rm.UserName;

        string result = repo.UpdateUserDetails(user);

        return RedirectToAction("Index");
    }

然后它重定向到其来源的用户列表,并将其回用的WebGrid助手视图索引anction方法。

每一次我打的库我源来自的DbContext对象用户最近的值:

    public List<User> GetAllUsersWithoutAdmin()
    {
        return context.Users.Where(x => x.Id != 1).OrderBy(x => x.FullName).ToList();
    }

    public User GetUser(int userId)
    {
        return context.Users.FirstOrDefault(x => x.Id == userId);
    }

    public string UpdateUserDetails(User user)
    {
        string info;

        try
        {
            User uUser = context.Users.FirstOrDefault(x => x.Id == user.Id);
            uUser.Category = user.Category;
            uUser.Email = user.Email;
            uUser.FullName = user.FullName;
            uUser.Login = user.Login;

            context.SaveChanges();
            info = "success";
        }
        catch (Exception err)
        {
            info = err.Message;
        }

        return info;
    }

还我使用UOW模式来解决在同一个控制器使用不同的存储库的问题:

public interface IUnitOfWork
{
    int SaveChanges();
}

每个版本库,那么实现这个接口:

    private ActivityLogContext context;

    public UserRepository(IUnitOfWork _context)
    {
        context = _context as ActivityLogContext;
    }

和共享它在其中在Ninject控制器厂通过AddBindings实现()方法的线程的范围相同的上下文:

    private void AddBindings()
    {
        ninjectKernel.Bind<IActivityRepository>().To<ActivityRepository>();
        ninjectKernel.Bind<IUserRepository>().To<UserRepository>();
        ninjectKernel.Bind<ICategoryRepository>().To<CategoryRepository>();
        ninjectKernel.Bind<IUnitOfWork>().To<ActivityLogContext>().InThreadScope();
    }

一个问题:对于一些奇怪的原因,一旦每隔一段时间,当用户对象正在编辑,上下文对象提出了用户属性错误的价值观。 这是发生在EF的的DbContext与实际数据之间的水平某处。 特别是,在SQL Server中的数据永远是正确的。 它看起来像EF是缓存的性能先前的值,并采取那些不是从数据库采购他们。 当这种行为正是发生我还没有看到,但它发生,而经常 - 当对象被编辑每一个第二或第三时间。 有时会发生几次的一行。

我已经使用在以前的应用程序相同的设置,一切都很好。 此时唯一的区别是,我使用的WebGrid助手,只有用的WebGrid助手页面似乎导致我的应用程序这个问题???

Answer 1:

请问您的数据正确地呈现,如果你试试这个?

加载实体AsNoTracking:

public List<User> GetAllUsersWithoutAdmin()
{
    return context.Users.AsNoTracking().Where(x => x.Id != 1)
        .OrderBy(x => x.FullName).ToList();
}

public User GetUser(int userId)
{
    return context.Users.AsNoTracking().FirstOrDefault(x => x.Id == userId);
}

取下保存之后的实体:

public string UpdateUserDetails(User user)
{
    string info;

    try
    {
        User uUser = context.Users.FirstOrDefault(x => x.Id == user.Id);
        uUser.Category = user.Category;
        uUser.Email = user.Email;
        uUser.FullName = user.FullName;
        uUser.Login = user.Login;

        context.SaveChanges();

        // detach the entity after saving it
        Context.Entry(uUser).State = System.Data.EntityState.Detached;

        info = "success";
    }
    catch (Exception err)
    {
        info = err.Message;
    }

    return info;
}

这会给你脱离实体未在EF背景跟踪,这种方式可能是或不是取决于你的应用程序是可以接受的。 即使你不能从长远来看,使用它,给它一个尝试,看看问题是否真的是EF缓存。



Answer 2:

我也注意到了这个问题。 为了演示,打开查看,直接让在dB的变化。 BANG你会看到的变化不会反映在您的视图。

EF不会缓存数据,只将“刷新”(字不好选择在这里)这个数据,如果你从数据库中读取的情况下也是你写的分贝的环境。

希望这点你诠释,他的正确的方向。



文章来源: Strange Entity Framework behaviour - caching?