【问题标题】:Custom Entity Naming Rule for EFEF 的自定义实体命名规则
【发布时间】:2014-04-24 00:20:02
【问题描述】:

我的 Visual Studio 项目中有一个 edmx 文件,当您将模型中的表插入 edmx 时,它的名称与数据库中的名称相同,例如,通过导入 myTable,您会得到一个名为myTable 和集合名称 myTables

在将表格添加到我的文件时,如何使表格符合自定义命名约定?因此,例如,添加 myTable 会生成一个名为 tblmyTable 且集名称为 tblmyTables 的实体。

【问题讨论】:

  • 亲爱的投反对票的人......当你对一个问题投反对票时,试着留下评论解释为什么投反对票,我认为我的问题很清楚,无论多么简短,如果你需要进一步的解释,我可以为你澄清。 .. 如果您对您的疑问发表评论。
  • 不是反对者,但我不清楚你想做什么。您的意思是在生成代码文件时使用自定义命名约定?
  • 已更新...希望够清楚。
  • 你可能想看看this answer然后
  • 谢谢,但我已经在使用自定义 T4 模板,但这些文件很大...我需要知道如何修改该文件以便自定义命名类。跨度>

标签: .net entity-framework visual-studio


【解决方案1】:

如果您使用的是旧的实体对象生成器 EF4.0 或 EF5.0:

需要多处修改<YourModelName>.tt文件。

模板调用container.BaseEntitySets.OfType<EntitySet>() 来获取您的所有实体集,其中返回的EntityeSet.ElementType(其中ElementType 的类型为EntityType)包含有关您的实体的信息。

这些对象在模板中的许多地方使用,因此最简单的解决方案是设置EntityTypeName 属性。但是Name 属性是内部的,因此您需要使用反射来设置它。

因此,在模板中的 第 163 行附近找到以下行:

region.Begin(CodeGenerationTools.GetResourceString("Template_RegionObjectSetProperties"));
foreach (EntitySet set in container.BaseEntitySets.OfType<EntitySet>())
{

您需要在此处添加以下代码来设置Name 属性:

region.Begin(CodeGenerationTools.GetResourceString("Template_RegionObjectSetProperties"));
foreach (EntitySet set in container.BaseEntitySets.OfType<EntitySet>())
{
      set.ElementType.GetType()
            .GetProperty("Name", 
               BindingFlags.Instance | 
               BindingFlags.Public | 
               BindingFlags.NonPublic | 
               BindingFlags.SetProperty)
         .SetValue(set.ElementType, "tbl" + set.ElementType.Name, null);

遗憾的是你还没有完成,因为你还需要改变两个地方:

首先生成的属性名称不固定,因此您需要在 line 173 周围找到以下行:

<#=code.SpaceAfter(NewModifier(set))#><#=Accessibility.ForReadOnlyProperty(set)#> ObjectSet<<#=MultiSchemaEscape(set.ElementType, code)#>> <#=code.Escape(set)#>

并将其更改为(在&lt;#=code.Escape(set)#&gt; 之前添加tbl

<#=code.SpaceAfter(NewModifier(set))#><#=Accessibility.ForReadOnlyProperty(set)#> ObjectSet<<#=MultiSchemaEscape(set.ElementType, code)#>> tbl<#=code.Escape(set)#>

由于反射黑客,您需要从生成的EdmEntityTypeAttribute 中删除“tbl”前缀,因此您需要在 line 295 周围找到以下行:

[EdmEntityTypeAttribute(NamespaceName="<#=entity.NamespaceName#>", Name="<#=entity.Name#>")]

并将其更改为:

[EdmEntityTypeAttribute(NamespaceName="<#=entity.NamespaceName#>", Name="<#=entity.Name.Replace("tbl","")#>")]

如果您使用默认的 EF DbContext 生成器 EF5.0 或 EF6.0 和 edmx:

您需要修改 tt 文件以应用您的自定义命名约定。

首先你应该修改&lt;YourEdmxName&gt;.tt文件:

第 23 行附近,您应该找到以下方法调用:

fileManager.StartNewFile(entity.Name + ".cs");

此方法创建您的实体类,因此如果您想修改生成的文件名,您需要将其更改为:

fileManager.StartNewFile("tbl" + entity.Name + ".cs");

然后在第307行附近你需要找到以下方法声明:

public string EntityClassOpening(EntityType entity)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1}partial class {2}{3}",
        Accessibility.ForType(entity),
        _code.SpaceAfter(_code.AbstractOption(entity)),
        _code.Escape(entity),
        _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}

此方法会写入您的类名,因此您需要在此处更改它以应用您的约定:

public string EntityClassOpening(EntityType entity)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1}partial class {2}{3}",
        Accessibility.ForType(entity),
        _code.SpaceAfter(_code.AbstractOption(entity)),
        "tbl" + _code.Escape(entity), // add tbl prefix before the entity name
        _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}

最后你需要修改你的&lt;YourEdmxName&gt;.Context.tt

第 296 行附近,您需要找到以下写出 DbSet 属性的方法:

public string DbSet(EntitySet entitySet)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} DbSet<{1}> {2} {{ get; set; }}",
        Accessibility.ForReadOnlyProperty(entitySet),
        _typeMapper.GetTypeName(entitySet.ElementType),
        _code.Escape(entitySet));
}

然后再次更改以应用您的约定:

public string DbSet(EntitySet entitySet)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} DbSet<{1}> {2} {{ get; set; }}",
        Accessibility.ForReadOnlyProperty(entitySet),
        // add "tbl" to the type name DbSet<Table> -> DbSet<tblTable>
        "tbl" + _typeMapper.GetTypeName(entitySet.ElementType), 
        // add "tbl" to property name Tables -> tblTables
        "tbl" + _code.Escape(entitySet));
}

【讨论】:

  • 我已经尝试解决这个问题好几天了。我不知道 EF 是否不同或其他原因,但我无法让它工作......我使用的是 EF v4.0,你的答案是否与写的一样?
  • @PedroC88 是的,我假设 EF5.0 或更高版本......您使用的是哪个 EF4 tt,您使用的是 POCO、Self Tracking 还是对象 EntityObject?您可以将当前的 tt 文件上传到某处并在此处发布链接吗?
  • 无法上传文件,如何知道我使用的tt类型?
  • @PedroC88 生成的类是什么样的?您是否有派生自 ObjectContextSomethingContainer 并且您的实体派生自 EntityObject 并有一些 EdmEntityTypeAttribute
  • 只剩下 5 分钟了,所以我给分了,因为你显然是在正确的轨道上。我做了所有新的改变,但仍然没有工作,我正在努力让它工作。会回帖。
猜你喜欢
  • 2017-02-22
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-02
  • 2018-10-26
  • 1970-01-01
  • 2013-07-19
相关资源
最近更新 更多