如何将DbSet <entityname>添加到使用Codedom动态生成的上下文中?

时间:2015-07-07 17:48:31

标签: c# entity-framework codedom

我正在使用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);

是我将生成的上下文的名称设为相应的实体名称+“Context”,因此在该行中我删除了“Context”以获取entityName。无论如何,那不是真的相关。给我带来麻烦的是第一类:

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

这只是给了我:

DbSet<>

但我需要:

DbSet<EntityName>

如果我尝试在尖括号内写任何内容,我会收到错误消息,说明它无法解析符号。例如,我想写:

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

我可以做出

Type entityType

此方法的参数,但它不喜欢。

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

2 个答案:

答案 0 :(得分:1)

如果我们了解问题的核心,那么您在此基本上要求的是如何使用反射来获取封闭泛型类型的类型。这与CodeDom或EntityFramework没有任何关系。

正如您所提到的,使用typeof(DbSet<>)(或List<>或其他任何内容)将为您提供&#34;开放泛型类型&#34;,表示特定泛型类型所基于的类型。从这里,您可以使用方法MakeGenericType来创建特定的封闭泛型类型:

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

答案 1 :(得分:1)

您需要使用开放式通用DbSet<>并将其关闭,如下所示:

typeof(DbSet<>).MakeGenericType(entityType)