【问题标题】:How to add DbSet<EntityName> to a context that is generated dynamically with Codedom?如何将 DbSet<EntityName> 添加到使用 Codedom 动态生成的上下文中?
【发布时间】:2015-07-08 02:16:24
【问题描述】:

我正在使用 Codedom 动态生成实体。我也没有硬编码的上下文类作为解决方案的一部分。也就是说,我也在运行时使用 Codedom 生成上下文。我这样做是为了让每个生成的实体都有自己的上下文。我在为上下文类编写 Codedom 代码时遇到了问题。作为上下文的一部分,我需要写入 DbSet 属性,以便生成的实体可以成为上下文模型的一部分。更具体地说,我在生成的上下文中需要以下行:

public DbSet<EntityName> EntityNames { get; set; }

其中 EntityName 是我创建的实体类类型的名称,而 EntityNames 就是那个以“s”结尾的名称。例如,我可能会创建一个 Employee 实体,所以我想生成一个上下文:

public DbSet<Employee> Employees { get; set; }

为此,我正在编写一个返回此 CodeMemberProperty 的方法。它知道要写 Employee/Employees,因为我传入了实体的名称。没关系。到目前为止,该方法看起来像这样:

public static CodeMemberProperty HardCodeDbSet(string contextName)
{
    string entityName = contextName.Substring(0, contextName.Length - 7);
    CodeMemberProperty prop = new CodeMemberProperty();
    prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
    prop.Name = entityName + "s";
    prop.Type = new CodeTypeReference(typeof(DbSet<>));
    return prop;
}

出现此行的原因:

string entityName = contextName.Substring(0, contextName.Length - 7);

是我将生成的上下文的名称设置为相应的实体名称+“上下文”,因此在该行中我删除了“上下文”以取回实体名称。无论如何,这并不重要。给我带来麻烦的是第一类:

prop.Type = new CodeTypeReference(typeof(DbSet<>));

这只是给了我:

DbSet<>

但我需要:

DbSet<EntityName>

如果我尝试在尖括号内写任何内容,我会收到一条错误消息,指出它无法解析符号。比如我想写:

prob.Type = new CodeTypeReference(typeof(DbSet<entityType>));

我可以做

Type entityType

这个方法的一个参数,但它不喜欢那样。

有人知道解决这个问题的方法吗?我认为编写此代码会简单得多,但 Codedom 并不像我想象的那样合作......

【问题讨论】:

  • 为什么要生成上下文?看看DbModelBuilder。还可以得到一些infos for types 另外:为什么每个实体一个上下文?你想达到什么目的?你的目标是什么?

标签: c# entity-framework codedom


【解决方案1】:

如果我们深入到问题的核心,您在这里的基本要求是如何使用反射来获取封闭泛型类型的 Type。这与 CodeDom 或 EntityFramework 没有任何关系。

正如您所提到的,使用typeof(DbSet&lt;&gt;)(或List&lt;&gt;,或其他任何东西)将为您提供“开放泛型类型”,即特定泛型类型所基于的类型。从这里,您可以使用方法MakeGenericType 创建特定的封闭泛型类型:

var openType = typeof(DbSet<>);
var closedType = openType.MakeGenericType(entityType);

【讨论】:

  • 感谢您的解释!我现在很清楚这个问题究竟是关于什么的。
  • 有时很难将森林与树木分开,尤其是在使用 CodeDom 或 EF 等复杂库时。 :)
【解决方案2】:

您需要使用打开的通用 DbSet&lt;&gt; 并将其关闭,如下所示:

typeof(DbSet<>).MakeGenericType(entityType)

【讨论】:

  • 感谢帮助 :) 我接受了另一个,因为他是第一个哈哈
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多