RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 747934
Accepted
Bald
Bald
Asked:2020-11-22 13:42:39 +0000 UTC2020-11-22 13:42:39 +0000 UTC 2020-11-22 13:42:39 +0000 UTC

如何设置多对多关系的键名?

  • 772

对于数据库开发,我使用代码优先的方法。有两个班

public class Assembly
{
    public int Id {get;set;}

    public virtual ICollection<OperationItem> Items {get;set;} = new List<OperationItem>();
}

public class OperationItem
{
    public int Id {get;set;}

    public virtual ICollection<Assembly> Assemblies {get;set;} = new List<Assembly>();
}

基于此,实体框架生成如下迁移:

CreateTable(
    "dbo.AssemblyOperationItems",
    c => new
        {
            Assembly_Id = c.Int(nullable: false),
            OperationItem_Id = c.Int(nullable: false),
        })
    .PrimaryKey(t => new { t.Assembly_Id, t.OperationItem_Id })
    .ForeignKey("dbo.Assemblies", t => t.Assembly_Id)
    .ForeignKey("dbo.OperationItems", t => t.OperationItem_Id)
    .Index(t => t.Assembly_Id)
    .Index(t => t.OperationItem_Id);

迁移脚本本身是正确的,我对分配的名称不满意:Assembly_Id & OperationItem_Id,并且在所有其他表中调用了键AssemblyId & OperationItemId。

_在创建多对多关系时,是否可以告诉 EF 在不使用名称中的键的情况下生成名称。

PS我知道如果您通过创建链接可以解决此问题fluent api,我对不同的解决方案,注释属性等感兴趣。

c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Alexcei Shmakov
    2020-11-22T16:12:37Z2020-11-22T16:12:37Z

    当使用多对多关系时,使用 FK 命名约定,不能用注解重载。根据命名约定,FK按照如下规则组成

    <表名>_<表主键名>

    我们在示例中看到的内容。

    要重新加载它,您可以执行以下操作:

    1. 如您所述,请像这样使用 FluentAPI:

      protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
          modelBuilder.Entity<Assembly>()
             .HasMany<OperationItem>(s => s.Items)
             .WithMany(c => c.Assemblies)
             .Map(cs =>
             {
                 cs.MapLeftKey("ItemsRefId");
                 cs.MapRightKey("AssembliesRefId");
      
             });
       }
      

      因此,我们将进行以下迁移:

      CreateTable(
                  "dbo.AssemblyOperationItems",
                  c => new
                      {
                          ItemsRefId = c.Int(nullable: false),
                          AssembliesRefId = c.Int(nullable: false),
                      })
                  .PrimaryKey(t => new { t.ItemsRefId, t.AssembliesRefId })
                  .ForeignKey("dbo.Assemblies", t => t.ItemsRefId, cascadeDelete: true)
                  .ForeignKey("dbo.OperationItems", t => t.AssembliesRefId, cascadeDelete: true)
                  .Index(t => t.ItemsRefId)
                  .Index(t => t.AssembliesRefId);
      
    2. 重新加载辅助键命名约定。

    当我们对标准命名约定不满意时,我们可以重载这个约定。从这里举个例子。
    让我们为辅助键定义一个名称重命名类,它将删除根据标准命名约定生成的 _ 字符。

    // Provides a convention for fixing the independent association (IA) foreign key column names.  
        public class ForeignKeyNamingConvention : IStoreModelConvention<AssociationType>
        {
    
            public void Apply(AssociationType association, DbModel model)
            {
                // Identify ForeignKey properties (including IAs)  
                if (association.IsForeignKey)
                {
                    // rename FK columns  
                    var constraint = association.Constraint;
                    if (DoPropertiesHaveDefaultNames(constraint.FromProperties, constraint.ToRole.Name, constraint.ToProperties))
                    {
                        NormalizeForeignKeyProperties(constraint.FromProperties);
                    }
                    if (DoPropertiesHaveDefaultNames(constraint.ToProperties, constraint.FromRole.Name, constraint.FromProperties))
                    {
                        NormalizeForeignKeyProperties(constraint.ToProperties);
                    }
                }
            }
    
            private bool DoPropertiesHaveDefaultNames(ReadOnlyMetadataCollection<EdmProperty> properties, string roleName, ReadOnlyMetadataCollection<EdmProperty> otherEndProperties)
            {
                if (properties.Count != otherEndProperties.Count)
                {
                    return false;
                }
    
                for (int i = 0; i < properties.Count; ++i)
                {
                    if (!properties[i].Name.EndsWith("_" + otherEndProperties[i].Name))
                    {
                        return false;
                    }
                }
                return true;
            }
    
            private void NormalizeForeignKeyProperties(ReadOnlyMetadataCollection<EdmProperty> properties)
            {
                for (int i = 0; i < properties.Count; ++i)
                {
                    int underscoreIndex = properties[i].Name.IndexOf('_');
                    if (underscoreIndex > 0)
                    {
                        properties[i].Name = properties[i].Name.Remove(underscoreIndex, 1);
                    }
                }
            }
        }
    

    我们在模型中包含二级键命名重载类,如下所示

            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                /*modelBuilder.Entity<Assembly>()
                    .HasMany<OperationItem>(s => s.Items)
                    .WithMany(c => c.Assemblies)
                    .Map(cs =>
                    {
                        cs.MapLeftKey("ItemsRefId");
                        cs.MapRightKey("AssembliesRefId");
    
                    });
                    */
    
                modelBuilder.Conventions.Add<ForeignKeyNamingConvention>();
            }
    

    结果,我们得到以下迁移

            CreateTable(
                    "dbo.OperationItemAssemblies",
                    c => new
                        {
                            OperationItemId = c.Int(nullable: false),
                            AssemblyId = c.Int(nullable: false),
                        })
                    .PrimaryKey(t => new { t.OperationItemId, t.AssemblyId })
                    .ForeignKey("dbo.OperationItems", t => t.OperationItemId, cascadeDelete: true)
                    .ForeignKey("dbo.Assemblies", t => t.AssemblyId, cascadeDelete: true)
                    .Index(t => t.OperationItemId, name: "IX_OperationItem_Id")
                    .Index(t => t.AssemblyId, name: "IX_Assembly_Id");
    

    您可能已经注意到,辅助键名称现在没有“ _ ”字符。

    • 6

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5