C# 实体框架6查询返回数据尚未保存在数据库中的记录

C# 实体框架6查询返回数据尚未保存在数据库中的记录,c#,ef-code-first,entity-framework-6,C#,Ef Code First,Entity Framework 6,我首先使用EntityFramework6代码创建了一个非常简单的测试项目,我试图了解更改跟踪是如何工作的 在我的简单测试中,我有一个Blogs表,我插入了一个名为“User1”的Blog,在插入和保存之后,我修改了用于插入的对象(name=“User1 modified”),但没有保存更改。紧接着我查询了我的数据库。令我惊讶的是,来自db的查询返回了修改过的记录,即使我在更新后没有保存我的更改。为什么呢 这是我的代码: class Program { static void Main

我首先使用EntityFramework6代码创建了一个非常简单的测试项目,我试图了解更改跟踪是如何工作的

在我的简单测试中,我有一个Blogs表,我插入了一个名为“User1”的Blog,在插入和保存之后,我修改了用于插入的对象(name=“User1 modified”),但没有保存更改。紧接着我查询了我的数据库。令我惊讶的是,来自db的查询返回了修改过的记录,即使我在更新后没有保存我的更改。为什么呢

这是我的代码:

 class Program
{
    static void Main(string[] args)
    {
        using (var db = new BloggingContext())
        {
            // Create and save a new Blog 
            Console.Write("Enter a name for a new Blog: ");
            //var name = Console.ReadLine();

            var name = "User1";

            var blog = new Blog { Name = name };
            db.Blogs.Add(blog);
            db.SaveChanges();

            //Modify my blog name but don't save changes yet!
            blog.Name = "User1 modified";

            // Display all Blogs from the database 
            var query = from b in db.Blogs
                        orderby b.Name
                        select b;

            Console.WriteLine("All blogs in the database:");
            foreach (var item in query)
            {
                //item.Name comes as "User1 modified" instead of "User1" Why?????
                Console.WriteLine(item.Name);
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        } 
    }
}
public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }
} 
类程序
{
静态void Main(字符串[]参数)
{
使用(var db=new BloggingContext())
{
//创建并保存新博客
Write(“输入新博客的名称:”);
//var name=Console.ReadLine();
var name=“User1”;
var blog=newblog{Name=Name};
添加(blog);
db.SaveChanges();
//修改我的博客名称,但不要保存更改!
blog.Name=“User1已修改”;
//显示数据库中的所有博客
var query=来自db.Blogs中的b
orderby b.Name
选择b;
WriteLine(“数据库中的所有博客:”);
foreach(查询中的var项)
{
//item.Name是“User1 modified”而不是“User1”为什么?????
Console.WriteLine(项目名称);
}
Console.WriteLine(“按任意键退出…”);
Console.ReadKey();
} 
}
}
公共类BloggingContext:DbContext
{
公共数据库集博客{get;set;}
}
公共类博客
{
public int BlogId{get;set;}
公共字符串名称{get;set;}
} 
我如何直接从数据库而不是上下文中获取数据,即使不保存更改,上下文似乎也保存着我的对象属性

谢谢


原始项目教程可以在这里找到:

DbContext是一个特性,它返回与您已经加载的对象相同的对象。
DbContext
缓存所有加载的对象,并提供一个一致的数据视图,您可以在一次调用
SaveChanges()
中更新和稍后保存这些数据


如果要从数据库中执行单独的查询,而不考虑未保存的更改,则应使用另一个
DbContext

执行该操作。我最终查询了我的实体
AsNoTracking
,如@LadislavMrnka所建议:

var query = from x context.YourEntities.AsNoTracking() where ... select x;


这将强制EF每次重新加载数据。它在我的情况下起作用,因为我只需要从返回的对象中读取一些数据,并且不保存任何更改。

问题是,在我当前的体系结构中,我只使用一个
DbContext
。因此,除了使用新的
DbContext
之外,没有其他方法可以查询未通过
SaveChanges
提交的数据?没有,并且您不应该只使用一个
DbContext
。它重量轻,仅用于单个“工作单元”的持续时间,从用户角度来看,这通常是一个逻辑保存操作(可能会更新数据库中的多个表)。您可以执行
dataContext.Entry(entityVariable).Reload()-这将从数据库中重新加载给定实体并覆盖本地更改。您想查询模型的以前状态吗?如果您需要在更改数据之前“记住”数据的某些信息,请在修改之前进行查询,并将相关信息存储在变量中。这很难解释。我正在进行一个集成测试,插入一个保险对象,然后修改一个属性,运行一个方法,从数据库中获取我的保险对象,并将新记录与现有记录进行比较,但在这种情况下,现有记录和新记录是相同的,因为我在重用上下文。在live app中不会发生,因为我确实在每个web事务上创建了一个新的上下文,但我想构建一个覆盖该用例的测试。在这个测试中,如果对象已更改(现有!=新),那么我需要创建一个新记录以保留历史记录。但这是不可能的,因为在重用上下文时,现有的总是==新的