EF的自定义实体命名规则

Ped*_*C88 7 .net entity-framework visual-studio

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

在将表添加到我的文件中时,如何使表遵循自定义命名约定?因此,例如,myTabletblmyTable使用Set Name 调用的实体中添加结果tblmyTables.

nem*_*esv 6

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

您需要<YourModelName>.tt在多个位置修改文件.

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

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

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

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

你需要在这里添加以下代码来设置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);
Run Code Online (Sandbox Code Playgroud)

可悲的是,你还没有完成,因为你仍然需要改变两个地方:

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

<#=code.SpaceAfter(NewModifier(set))#><#=Accessibility.ForReadOnlyProperty(set)#> ObjectSet<<#=MultiSchemaEscape(set.ElementType, code)#>> <#=code.Escape(set)#>
Run Code Online (Sandbox Code Playgroud)

并将其更改为(添加tbl之前<#=code.Escape(set)#>:

<#=code.SpaceAfter(NewModifier(set))#><#=Accessibility.ForReadOnlyProperty(set)#> ObjectSet<<#=MultiSchemaEscape(set.ElementType, code)#>> tbl<#=code.Escape(set)#>
Run Code Online (Sandbox Code Playgroud)

由于反射黑客,你需要删除生成的"tbl"前缀,EdmEntityTypeAttribute所以你需要在第295行找到以下行:

[EdmEntityTypeAttribute(NamespaceName="<#=entity.NamespaceName#>", Name="<#=entity.Name#>")]
Run Code Online (Sandbox Code Playgroud)

并将其更改为:

[EdmEntityTypeAttribute(NamespaceName="<#=entity.NamespaceName#>", Name="<#=entity.Name.Replace("tbl","")#>")]
Run Code Online (Sandbox Code Playgroud)

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

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

首先你应该修改<YourEdmxName>.tt文件:

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

fileManager.StartNewFile(entity.Name + ".cs");
Run Code Online (Sandbox Code Playgroud)

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

fileManager.StartNewFile("tbl" + entity.Name + ".cs");
Run Code Online (Sandbox Code Playgroud)

然后在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)));
}
Run Code Online (Sandbox Code Playgroud)

这个方法编写你的类名,所以在这里你需要改变它来应用你的约定:

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)));
}
Run Code Online (Sandbox Code Playgroud)

最后你需要修改你的<YourEdmxName>.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));
}
Run Code Online (Sandbox Code Playgroud)

并再次更改它以应用您的约定:

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));
}
Run Code Online (Sandbox Code Playgroud)