【问题标题】:db.SaveChanges Saves record in Database but Application doesn't updatedb.SaveChanges 在数据库中保存记录但应用程序不更新
【发布时间】:2015-03-12 16:06:09
【问题描述】:

我正在尝试通过 AJAX POST 更改用户当前的文化:

$.ajax({
    type: 'POST',
    url: '/Account/SetDefaultCulture',
    data: data,
    dataType: 'JSON',
    success: function (result) {
      location.reload(true);
    }
  });

使用此控制器方法:

private readonly AspEntities db = new AspEntities();
[HttpPost]
    public JsonResult SetDefaultCulture(string userName, string culture)
    {
      if (!userName.IsNullOrEmpty())
      {
        var user = (from a in _db.AspNetUsers
                where a.UserName == userName
                select a).FirstOrDefault();
        if (user != null)
        {
          user.Culture = culture;
          db.SaveChanges();
          Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
          return Json(new { culture, success = true });
        }
      }

      return Json(new {culture, success = false});
    }

如果我在调试时单步执行,我可以在调用 db.SaveChanges() 后立即看到数据库记录更新。

问题是应用程序/网站不会更新用户的文化,直到我更改控制器中的一些代码,然后再次构建项目。就好像文化被缓存在应用程序或其他东西中一样。

我一定错过了什么。这很常见吗?有人遇到过吗?

编辑

我正在使用 Utility 方法来检查当前用户的文化:

public static CultureInfo GetCulture()
{
  var userId = HttpContext.Current.User.Identity.GetUserId();
  var user = (from a in _db.AspNetUsers
              where a.Id == userId
              select a).FirstOrDefault();
  var culture = "en-CA";

  if (user != null)
  {
    if (!user.Culture.IsNullOrEmpty())
    {
      culture = user.Culture;
    }
  }

  return new CultureInfo(culture);
}

在每个页面点击时运行的过滤器中:

public class CheckCultureAttribute : ActionFilterAttribute
{
  public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    HttpContext ctx = HttpContext.Current;
    string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower().Trim();
    string actionName = filterContext.ActionDescriptor.ActionName.ToLower().Trim();

    //Set Culture
    var culture = (ctx.User != null) ? Utilities.GetCulture() : new CultureInfo("en-CA");
    Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = culture;

    ...
  }
}

如果我启动调试器并单步执行此过滤器,GetCulture() 方法会返回未更新的值(与数据库中已更新的值不匹配)

【问题讨论】:

  • 您是在每次点击页面时从数据库中提取用户当前的文化,还是将其缓存在会话变量(或用户 cookie?)中?
  • 从每个页面点击的数据库中。我还没有设置 cookie,虽然这是我的下一个待办事项列表,呵呵
  • 这一行Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = new CultureInfo(culture); 不会做太多事情,因为线程即将在下一个语句(返回)处结束。据我所知,问题不在于您提供的代码。
  • @RobertMcKee 我刚刚使用每次页面加载时运行的过滤器方法更新了问题。我只是尝试在SetDefaultCulture 中的return 语句之前设置Culture 作为测试,尽管我知道它会被Filter 方法设置的任何内容覆盖。
  • 用户数据正在通过 cookie 或会话进行持久化。它不是在每个页面点击时查找用户。而且由于您将文化数据保存在 AspNetUsers 表中,因此很可能它也被保存在 cookie 或会话中。

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


【解决方案1】:

似乎 EF 没有跟踪您的更改。 试试这样的,

db.Entry(AspNetUsers).State = EntityState.Modified;

之前:db.SaveChanges();

此外,您正在查询 _db 上下文,而我可以看到您的上下文是 私有只读 AspEntities db = new AspEntities();

哪些提示您的上下文设置不正确?不知道我是否正确,但请检查您的上下文。

【讨论】:

  • 太晚了...你已经将数据持久化到数据库了哈哈..真是个假人
  • 你的过滤器在哪里?它是在行动中还是在控制器中还是在全局中?
【解决方案2】:

还不能评论,但你检查过this other stack overflow question

根据该链接,操作过滤器似乎已经为时已晚,无法为请求设置文化。

【讨论】:

    【解决方案3】:

    检查您是否在应该产生更新的控制器中引用来自已经实例化的数据库上下文 (AspEntities db) 的数据。 readonly 修饰符将阻止声明后的更改,除非您始终创建新的控制器对象。

    【讨论】:

      【解决方案4】:

      我认为您首先必须将用户附加到您的 DbContext。

      db.AspNetUsers.Attach(user);
      

      然后调用保存更改。每次我在更新数据库时遇到问题,这就是原因。我相信您也必须在此更新后刷新页面。

      【讨论】:

      • 嗨@JRT,我刚试过,但没有解决我的问题。不过感谢您的建议!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-26
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      相关资源
      最近更新 更多