【问题标题】:How to change the naming convention of Many-to-Many table relationships?如何更改多对多表关系的命名约定?
【发布时间】:2013-09-28 16:41:21
【问题描述】:

如何更改自动生成的多对多表的命名约定?

假设我有两个类:

public class User
{
    public int UserId { get; set; }
    public virtual List<Role> Roles { get; set; }
}

public class Role
{
    public int RoleId { get; set; }
    public virtual List<User> Users { get; set; }
}

默认情况下,这将创建一个名为 UserRoles 的表。

我可以将该 一个 表的名称更改为 UsersInRoles,例如,通过在我的 DbContext 的 OnModelCreating 覆盖中使用以下内容:

modelBuilder.Entity<User>()
    .HasMany(p => p.Roles)
    .WithMany(p => p.Users)
    .Map(mc =>
    {
        mc.MapLeftKey("UserId");
        mc.MapRightKey("RoleId");
        mc.ToTable("UsersInRoles");
    });

但是,我真正想做的是更改命名约定,以便默认情况下,所有自动生成的多对多表都使用这个新约定。我无法弄清楚如何做到这一点,或者是否有可能。我不喜欢每次指定其中一种关系时都必须指定 9 行额外代码。

我目前使用的是 EF 版本 6.0.0-rc1。

【问题讨论】:

  • 出于好奇,您为什么真的想这样做?当您不断使用不同的编码时,按惯例编码就会失去所有魅力。
  • 你可以看看Custom Conventions
  • @TonyHopkinson,在我的真实场景中,我正在编写一个框架,该框架会根据其“组件”位置(例如 Core、HR、Finance 等)更改所有带有前缀的表名。虽然我能够为标准表重命名编写一个包罗万象的方法,但它不适用于这些多对多表,我不知道怎么做。至于我的示例,我已经使用该约定很长时间了,并且愿意坚持下去。
  • @GertArnold,我知道您可以编写自定义约定,但仍然不知道我将如何解决这个特定问题,无论是使用自定义约定还是直接使用 DbModelBuilder。
  • 恐怕我没有答案。我知道有一些方法可以破坏约定,但我怀疑它们是故意让人痛苦的。

标签: entity-framework ef-code-first entity-framework-6


【解决方案1】:

在发布之前,控制关系的功能已从基本约定 API 中删除,因为它不处于可用状态。您可以通过基于模型的约定访问模型中的所有属性和表。此处提供了基于模型的约定的概述:http://msdn.microsoft.com/en-US/data/dn469439

这个解决方案涉及更多元数据 API 的挖掘,EntitySet 是这个场景的正确类型

这个约定应该重命名生成的关系表:

public class MyConvention : IStoreModelConvention<EntitySet>
{
    public void Apply(EntitySet set, DbModel model)
    {
        var properties = set.ElementType.Properties;
        if (properties.Count == 2)
        {
            var relationEnds = new List<string>();
            int i = 0;
            foreach (var metadataProperty in properties)
            {
                if (metadataProperty.Name.EndsWith("_ID"))
                {
                    var name = metadataProperty.Name;
                    relationEnds.Add(name.Substring(0, name.Length - 3));
                    i++;
                }
            }
            if (relationEnds.Count == 2)
            {
                set.Table = relationEnds.ElementAt(0) + "_" + relationEnds.ElementAt(1) + "_RelationTable";
            }
        }
    }

【讨论】:

  • 我玩过这个,但发现 EntityType 约定不允许我重命名表。 Set Name 属性是内部的。再说一次,我不得不手动重命名每个表。
  • 上述约定是否解决了您的问题,或者您还需要其他什么?
  • 不,那是完美的!不能说我几乎和我应该熟悉的 EDM 部分一样熟悉,但这很好用。谢谢!
猜你喜欢
  • 2016-09-21
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 2021-06-23
  • 2016-04-26
  • 1970-01-01
  • 2012-03-22
  • 2021-10-26
相关资源
最近更新 更多