【问题标题】:Entity Framework 6 query returning record with data not yet saved in the database实体框架 6 查询返回记录,其中的数据尚未保存在数据库中
【发布时间】:2014-03-08 17:15:27
【问题描述】:

我使用 Entity Framework 6 Code-first 创建了一个非常简单的测试项目,我试图了解更改跟踪的工作原理。

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

这是我的代码:

 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; }
} 

如何直接从数据库而不是 Context 中获取数据,即使不保存更改,它似乎也保留了我的对象属性?

谢谢!

原始项目教程可以在这里找到:http://msdn.microsoft.com/en-us/data/jj193542.aspx

【问题讨论】:

  • 为什么要查询模型的先前状态?如果您需要在更改之前“记住”您的数据的某些内容,请在修改之前进行查询并将相关信息存储在变量中。
  • 很难解释。我正在进行集成测试,在其中插入一个被保险人对象,然后我修改一个属性并运行一个方法,该方法从数据库中获取我的被保险人并将新记录与现有记录进行比较,但在这种情况下,现有记录和新记录是相同的因为我正在重用上下文。在实时应用中不会发生,因为我确实在每个 Web 事务上创建了一个新上下文,但我想构建一个涵盖该用例的测试。
  • 在这个测试中,如果对象发生了变化(现有的!=新的)那么我需要创建一个新的记录来保存历史。但这是不可能的,因为在重用 Context 时,existing 总是 == new

标签: c# ef-code-first entity-framework-6


【解决方案1】:

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

如果您想从不考虑未保存更改的数据库中进行单独查询,您应该使用另一个 DbContext

【讨论】:

  • 问题是在我当前的架构中我只使用了一个DbContext。那么除了使用新的DbContext之外,没有办法查询没有通过SaveChanges提交的数据?
  • 不,你不应该只使用一个DbContext。它旨在轻量级,仅用于单个“工作单元”的持续时间,从用户角度来看,这通常是一个逻辑保存操作(可能会更新数据库中的多个表)。
  • 你可以做dataContext.Entry(entityVariable).Reload(); - 这将从数据库中重新加载给定的实体并覆盖本地更改
【解决方案2】:

我最终按照@LadislavMrnka 的建议查询了我的实体AsNoTracking

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

How to force EF Code First to query the database?

这会强制 EF 每次重新加载数据。它适用于我的情况,因为我只需要从返回的对象中读取一些数据并且我没有保存任何更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多