【问题标题】:Foreign key navigation property naming convention alternatives外键导航属性命名约定替代方案
【发布时间】:2012-03-21 23:38:35
【问题描述】:

使用 Entity Framework 4.1 时,导航属性的命名约定是否有替代方案?

例如,不要这样做:

public virtual MyObject MyObject { get; set; }

成为

public virtual MyObject SomeOtherName { get; set; }

更新:

添加[ForeignKey("OldStepId")][ForeignKey("NewStepId")]属性后,生成的SQL就变成了:

{SELECT 
`Extent1`.`CompletedId`, 
`Extent1`.`OldStepId`, 
`Extent1`.`NewStepId`, 
`Extent1`.`Name`, 
`Extent1`.`Step_StepId`, 
`Extent1`.`Step_StepId1` 
FROM `Completed` AS `Extent1`}

其中,最后两列不存在。

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

    您可以使用 Data Annotations 或 Fluent API 来执行此操作

    属性方式

    public virtual Int32 MyObjectId{get;set;}
    [ForeignKey("MyObjectId")]
    public virtual MyObject SomeOtherName { get; set; }
    

    流畅的方式

    modelBuilder.Entity<Type>()
        .HasRequired(p => p.SomeOtherName)
        .WithMany(d => d.Type)
        .HasForeignKey(p => p.MyObjectId)
    

    对更新的响应

    如果您的 MyOjbect 类中有一个 List,那么您需要将该 List 标记为 [InverseProperty("SomeOtherName")]。这可能就是您在 SQL 中获得额外列的原因。通过告诉生成器主列的真正位置,这可以防止双向关系加倍。

    【讨论】:

    • 这实际上是不正确的,将变量命名为与约定不同的名称会导致错误,我希望有人可能知道解决方法。
    • @TravisJ 然后在你的问题中提出这个问题。我使用名称与类型名称不同的导航引用属性,没有任何问题;如果您在问题中详细说明什么无效以及何时无效,您可能会得到更有用的答案(我也会看看)。
    • @TravisJ 你是对的,这是我对公约的错误记忆。我已经习惯了使用数据属性看到这一点,以至于我忘记了它是约定。
    • @Justin - 响应您对属性的编辑:您可以包含外键是正确的,但是 EF 将在表单中缺少导航属性 MyObject 时出现错误Unknown column 'Extent1.MyObject_whatevertheprimarykeyis' in 'field list'
    • @TravisJ Hrmmm,我再次更新了它,如果您添加 Id 属性,这应该可以工作。这可能是您遇到错误的地方。
    【解决方案2】:

    我通常将它们称为与导航道具的外键相同的名称。

    【讨论】:

    • 我想不出不遵守这个约定的理由,所以我总是这么说。不过,我会得到纠正。
    【解决方案3】:

    如果您添加 T4 模板来生成内容,您几乎可以将命名方案调整为您想要的任何内容...

    【讨论】:

      【解决方案4】:

      您可以随意命名它们。您必须区分在类中具有(标量)外键属性的导航属性(“外键关联”)和没有(“独立关联”)的导航属性:

      外键关联

      [ForeignKey("VeryDifferentFKPropertyName")]     // refers to property, NOT column
      public virtual MyObject SomeOtherName { get; set; }
      
      [Column("JustAnotherColumnName")]               // map property to column name
      public int VeryDifferentFKPropertyName { get; set; }
      

      使用流畅的 API:

      modelBuilder.Entity<SomeEntity>()
          .HasRequired(e => e.SomeOtherName)   // or .HasOptional(...)
          .WithMany()
          .HasForeignKey(e => e.VeryDifferentFKPropertyName);
      
      modelBuilder.Entity<SomeEntity>()
          .Property(e => e.VeryDifferentFKPropertyName)
          .HasColumnName("JustAnotherColumnName");
      

      独立协会

      public virtual MyObject SomeOtherName { get; set; }
      

      您只能使用 Fluent API 映射外键列名称:

      modelBuilder.Entity<SomeEntity>()
          .HasRequired(e => e.SomeOtherName)   // or .HasOptional(...)
          .WithMany()
          .Map(a => a.MapKey("JustAnotherColumnName"));
      

      【讨论】:

        猜你喜欢
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 2010-09-17
        • 2012-04-25
        • 1970-01-01
        • 1970-01-01
        • 2012-12-03
        • 1970-01-01
        相关资源
        最近更新 更多