【问题标题】:Refresh / Recreate an EF object context in code or on application load在代码或应用程序加载时刷新/重新创建 EF 对象上下文
【发布时间】:2011-09-17 10:02:40
【问题描述】:

在代码中,有没有办法在 Visual Studio 中的 add New Item --> Entity Data Model 下创建对象上下文时执行什么操作?

例如,我在数据库中添加了一个新表。下次我加载使用该数据库模型的应用程序时,它会刷新模型并自动为该新表创建默认概念映射。

我可能会使用 ESQL 来查询数据库而不是 LINQ-To-Entities,所以我不在乎是否有对新实体集/对象的强类型访问。

此外,此解决方案是否会首先需要 EF 代码?

【问题讨论】:

  • 如果你想创建一个动态数据模型,你应该去 CodeFirst

标签: visual-studio entity-framework entity-framework-4 objectcontext


【解决方案1】:

你为什么要这样做?

我不知道如何使这成为可能。当您创建实体模型时,您实际上会创建一个基本上是 xml 的 edmx 文件。运行时你不能修改这些定义文件。从此 edmx 文件中,T4 模板生成上下文和 .NET 类/实体。据我所知,您不能在运行时将类定义添加到模型/上下文中。

也许这篇文章也可以提供更多见解EF retrieve entities from undefined table/view。否则,我们希望 Ladislav Mrinka 或 Julie Lerman 加入这个问题;)

先说一下EF代码。这不会有任何区别,因为代码优先方法也是一个 edmx 文件/实体模型,但是然后从中生成数据库(而不是从数据库中生成实体模型)最终结果是相同的并且不起作用运行时不同。

【讨论】:

  • 如果可能的话,我不喜欢使用内置的 Visual Studio 向导。出于同样的原因,我不喜欢在使用 WCF 时使用“添加服务引用”,例如——我更喜欢使用 ChannelFactory 创建代理。只是在寻找一个类似的概念,以动态地从数据库中生成 EDM。它不必在运行时,可以是编译时。
  • 这样啊。也不要使用添加服务引用。 Channelfactory 具有通用服务调用结构和 RetryCount 等。但是......MayBe T4 可能适合您。要编写自己的模板来检查数据库,请创建实体模型并生成类。
  • 我试试看。你知道 EF 视图是否可以引用模型中没有的表吗?就像如果我创建一个仅视图的 edmx,然后创建一个新的 DefiningQuery 来引用我在底层 sql 数据库中添加的一些新表,但根本不在模式下,它会工作吗?
  • 行不通...请参阅我在答案中的链接。对于 T4 模板的编码 -> 我相信这不是一件容易的事。为什么如此厌恶使用 VS 的内置向导?它具有(表、视图、存储过程)和刷新功能。
【解决方案2】:

嗯,.edmx 文件仅适用于 Visual Studio,不会成为应用程序的一部分。元数据存储在三个 xml 文件中,您可以在运行时加载它们:

http://blogs.msdn.com/b/alexj/archive/2010/01/27/tip-51-how-to-load-ef-metadata-from-an-arbitrary-stream.aspx

您必须将实体映射到类,这就是它变得丑陋的地方。可以在运行时使用反射 API 生成类。或者只是采用具有许多属性的泛型类,例如 StringProperty1、StringProperty2。

SQL 比 ESQL 更适合您的目的。

学习英孚: http://www.testmaster.ch/EntityFramework.test

【讨论】:

    【解决方案3】:

    我认为带有 EDMX 的 EF 还没有准备好应对这种情况。让我澄清一下原因:

    • EDMX 只是设计者使用的文件。在运行时,您需要从 EDMX 文件生成的 3 个 XML 文件(SSDL、MSL 和 CSDL)。这些文件定义了模型,它们是实体连接字符串的一部分。
    • ObjectContext 只能使用这些文件中提供的实体。
    • 标准方法是在每个连接/上下文中使用一组这些文件。一旦您遵循标准方法,您就会非常困难,因为添加表意味着修改这些 XML 文件(您必须使用单独部署这些文件的方法 - 默认方法使用这些文件作为数据访问程序集中的资源)。
    • 我描述了如何hack EF to allow multiple files per single connection,但我不推荐它。
    • 如果您创建单独的元数据文件集,您将需要另一个上下文实例来处理新实体(另一个连接字符串),这两个上下文将不知道彼此,也无法使用映射到另一个上下文中的实体。
    • 映射只是故事的一部分。现在您需要一个在应用程序中代表您的实体的类!如果您只希望这种“动态”行为仅用于开发,那么您可以,但是在运行时或重新加载应用程序时将表添加到模型中似乎不是一种方法 - 在 ORM 工具中定义模型是为了设计时间而不是运行时 = 你需要使用您的新实体编译程序集,您需要一个代码来使用这些新实体并引用您的新程序集。

    DefiningQuery 只是数据库查询 - 您可以使用数据库(甚至其他数据库)中存在的任何表,因为 EF 只对此查询的结果集感兴趣。

    使用代码优先,您将获得更好的开发体验。代码优先不需要 EDMX 文件 - 它使用代码定义的映射。您将需要您的应用程序在引导程序中从预定义(或所有引用的)程序集中收集从 EntityTypeConfiguration<> 派生的所有类型。所有这些配置将在创建第一个上下文实例时添加到OnModelCreation 中的DbModelBuilder。在重新启动应用程序并使用实体部署新程序集后,您将拥有一个可以轻松使用任何新实体的上下文。您仍然需要代码才能使用此实体。您必须手动创建 DbSet,而不是通过调用 context.Set<EntityType>() 将它们公开为上下文类的属性。首先使用代码执行此操作时存在一些问题,因为您必须关闭实体模型验证和数据库重新创建,并且您必须自己保持所有同步。

    我们仍在讨论部署新程序集以及重新启动应用程序时将使用该程序集的方案。如果您需要从应用程序本身管理表和“实体”,那么这不是直接使用 ORM 的场景。那是针对一些元数据模型/多租户场景,它的完成方式完全不同,其中 ORM 用于一些通用抽象表,而真实实体是从存储为抽象的元数据构造的。

    【讨论】:

      猜你喜欢
      • 2014-09-03
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-09
      • 1970-01-01
      相关资源
      最近更新 更多