Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 奇怪的实体框架行为-缓存?_C#_Entity Framework_Caching_Asp.net Mvc 4_Webgrid - Fatal编程技术网

C# 奇怪的实体框架行为-缓存?

C# 奇怪的实体框架行为-缓存?,c#,entity-framework,caching,asp.net-mvc-4,webgrid,C#,Entity Framework,Caching,Asp.net Mvc 4,Webgrid,我有ASP.NET MVC 4应用程序,使用EF 4.3进行迁移。我使用WebGrid帮助程序为系统用户显示详细信息: @grid.GetHtml( headerStyle: "gridHeader", footerStyle: "gridFooter", firstText: "<< First", previousText: "< Previous", nextText: "Next >", lastText: "Last >>", alternatin

我有ASP.NET MVC 4应用程序,使用EF 4.3进行迁移。我使用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>
    )                                                
})
然后,它重定向到Index anction方法,该方法生成用户列表,并通过WebGrid Helper将其传递回视图

每次访问存储库时,我都会从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;
    }
然后,每个存储库实现此接口:

    private ActivityLogContext context;

    public UserRepository(IUnitOfWork _context)
    {
        context = _context as ActivityLogContext;
    }
并在线程范围内的同一上下文中共享它,该线程由AddBindings()方法在Ninject控制器工厂中实现:

private void AddBindings()
{
ninjectKernel.Bind().To();
ninjectKernel.Bind().To();
ninjectKernel.Bind().To();
ninjectKernel.Bind().To().InThreadScope();
}

一个问题: 出于某种奇怪的原因,在编辑用户对象时,上下文对象常常会为用户属性显示错误的值。它发生在DbContext和实际数据之间的某个EF级别上。特别是,SQL server中的数据总是正确的。看起来EF正在缓存以前的属性值,并获取这些值,而不是从数据库中获取这些值。我并没有观察到这种行为到底发生在什么时候,但它经常发生——每秒钟或第三次编辑对象。有时它会连续发生几次


我在以前的应用程序中使用了相同的设置,一切都很好。这次唯一的不同是我使用的是WebGrid Helper,只有带有WebGrid Helper的页面似乎会在我的应用程序中导致此问题???

我也注意到了这种行为。为了演示,打开视图,直接在数据库中进行更改。砰的一声,你会发现变化并没有反映在你的观点中

EF会缓存数据,如果从dB读取的上下文也是您使用的写入dB的上下文,则EF只会“刷新”(此处的单词选择错误)此数据


希望这能给你指明正确的方向。

我也注意到了这种行为。为了演示,打开视图,直接在数据库中进行更改。砰的一声,你会发现变化并没有反映在你的观点中

EF会缓存数据,如果从dB读取的上下文也是您使用的写入dB的上下文,则EF只会“刷新”(此处的单词选择错误)此数据


希望这为您指明了正确的方向。

如果您尝试此操作,您的数据渲染是否正确

使用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);
}

这将为您提供在EF上下文中无法跟踪的分离实体,根据您的应用程序,这种方法可能是可接受的,也可能是不可接受的。即使您无法长期使用它,也可以尝试一下,看看问题是否真的是EF缓存。

如果您尝试此操作,您的数据渲染是否正确

使用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);
}

这将为您提供在EF上下文中无法跟踪的分离实体,根据您的应用程序,这种方法可能是可接受的,也可能是不可接受的。即使您无法长期使用它,也可以尝试一下,看看问题是否真的是EF缓存。

谢谢您的帮助。我仍然没有想到如何解决这个问题,因为我是通过编辑操作方法中的上下文进行更改的,所以应该反映出来谢谢帮助。我仍然没有想到如何解决这个问题,因为我是通过编辑操作方法中的上下文进行更改的,所以应该反映出来。如果它进行了任何更改,我将尝试。您的解决方案很有帮助!但我只能在你在回答中强调的两种方法中使用它。无法在编辑中使用它,因为我需要跟踪那里的更改。您的解决方案似乎解决了问题,但我仍然不知道是什么导致了问题。System.Data.EntityState.Detached在EF 6.1中成为System.Data.Entity.EntityState.Detached。如果它做了任何更改,我将尝试。您的解决方案很有帮助!但我只能在你在回答中强调的两种方法中使用它。无法在编辑中使用它,因为我需要跟踪那里的更改。您的解决方案似乎解决了问题,但我仍然不知道是什么导致了问题。System.Data.EntityState.Detached在EF 6.1中成为System.Data.Entity.EntityState.Detached
    private ActivityLogContext context;

    public UserRepository(IUnitOfWork _context)
    {
        context = _context as ActivityLogContext;
    }
    private void AddBindings()
    {
        ninjectKernel.Bind<IActivityRepository>().To<ActivityRepository>();
        ninjectKernel.Bind<IUserRepository>().To<UserRepository>();
        ninjectKernel.Bind<ICategoryRepository>().To<CategoryRepository>();
        ninjectKernel.Bind<IUnitOfWork>().To<ActivityLogContext>().InThreadScope();
    }
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;
}