【问题标题】:How to force EF Code First to query the database?如何强制 EF Code First 查询数据库?
【发布时间】:2011-10-05 06:47:36
【问题描述】:

我有一个管理规则集合的站点和一个单独的 Windows 窗体应用程序,该应用程序根据数据库中的规则进行文件级别的更改。

这两个应用程序都对 EF Code First DbContext 使用相同的库,但每个应用程序都在实例化自己的上下文副本。

问题是,上下文的每个运行版本都不知道其他版本所做的更改。例如。如果我更改网站上的规则,表单应用程序仍然具有以前的版本。

我知道我可能会采取这种错误的方式,并且应该通过 JSON/REST 从网站访问表单应用程序的某种数据,但出于其他原因我不希望这样做。

有没有办法在上下文中“禁用缓存”并强制每个查询访问数据库?

【问题讨论】:

    标签: entity-framework-4 ef-code-first


    【解决方案1】:

    不,没有办法禁用缓存。您必须手动设置每个查询以重新加载数据。该功能不适用于 DbContext API => 您必须使用 ObjectContext API。

    ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
    ObjectSet<YourEntity> set = objectContext.CreateObjectSet<YourEntity>();
    set.MergeOption = MergeOption.OverwriteChanges;
    var query = from x in set where ... select x;    
    

    或者更简单的场景:如果可能,使用更好的上下文管理,而不是在相同的上下文中运行查询,而是使用新的上下文。

    顺便说一句。将服务暴露在 winform 应用程序中并由网站使用的想法是错误的。您将需要第三个服务应用程序(托管在 Web 服务器上或作为 Windows 服务),并且网站和 winform 应用程序都将通过该新应用程序访问数据库。 EF 将仅在新应用程序中。

    编辑:

    如果您的 WinForm 应用程序不更改从数据库加载的数据,您也可以使用这个:

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

    这将关闭实体的内部更改跟踪,并且还应该强制 EF 每次重新加载实体,但这会使保存更改变得更加困难。

    【讨论】:

    • 我喜欢更简单的场景 :) 我目前通过构造函数通过 DI 创建了存储库。我想我必须取消它并根据需要使用服务定位器来生成新的上下文?
    • 假设“YourEntity”有相关的“Users”实体,它们没有用 MegeOption.OverwriteChanges 刷新,关于如何刷新 YourEntity.Users 有什么建议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多