【问题标题】:Mapping a foreign key with a custom column name使用自定义列名映射外键
【发布时间】:2012-06-24 07:23:04
【问题描述】:

我在 Oracle 中使用 Entity Framework 4.3 代码优先。我收到以下错误:

System.InvalidOperationException:类型“WidgetDistributor.WidgetEntity”的属性“WidgetSequence”上的 ForeignKeyAttribute 无效。在依赖类型“WidgetDistributor.WidgetEntity”上找不到外键名称“WIDGETSEQUENCE_ID”。 Name 值应该是逗号分隔的外键属性名称列表。

我的实体是这样的:

[Table("WIDGETENTITIES")]
public class WidgetEntity {

    [Column("WIDGETENTITY_ID")]
    public int Id { get; set; }

    [ForeignKey("WIDGETSEQUENCE_ID")]
    public WidgetSequence Sequence { get; set; }

    // and other properties that map correctly
}

[Table("WIDGETSEQUENCES")]
public class WidgetSequence { 

    [Column("WIDGETSEQUENCE_ID")]
    public int Id { get; set; }

    [Column("NUMBER")]
    public int Number { get; set; }
}

我的代码似乎正确。我做错了什么,在这里?

【问题讨论】:

    标签: c# oracle ef-code-first entity-framework-4.3


    【解决方案1】:

    如果您不想使用流畅的语法,还有其他三种使用数据注释来实现引用的方法(我个人更喜欢数据注释,因为它们看起来更容易阅读并且写在它们影响的属性之上):

    1.1) 使用 ForeignKey(带有关联属性) - 版本 1

    [Table("WIDGETENTITIES")]
    public class WidgetEntity {
    
        [Column("WIDGETENTITY_ID")]
        public int Id { get; set; }
    
        [Column("WIDGETSEQUENCE_ID")]
        public int WidgetSequenceId { get; set; }
    
        [ForeignKey("WidgetSequenceId")] //Has to be a property name, not table column name
        public WidgetSequence Sequence { get; set; }
    
        // and other properties that map correctly
    }
    
    [Table("WIDGETSEQUENCES")]
    public class WidgetSequence { 
    
        [Column("WIDGETSEQUENCE_ID")]
        public int Id { get; set; }
    
        [Column("NUMBER")]
        public int Number { get; set; }
    }
    

    1.2) 使用 ForeignKey(带有关联属性) - 版本 2

    [Table("WIDGETENTITIES")]
    public class WidgetEntity {
    
        [Column("WIDGETENTITY_ID")]
        public int Id { get; set; }
    
        [ForeignKey("Sequence")] //Has to be a property name, not table column name
        [Column("WIDGETSEQUENCE_ID")]
        public int WidgetSequenceId { get; set; }
    
        public WidgetSequence Sequence { get; set; }
    
        // and other properties that map correctly
    }
    
    [Table("WIDGETSEQUENCES")]
    public class WidgetSequence { 
    
        [Column("WIDGETSEQUENCE_ID")]
        public int Id { get; set; }
    
        [Column("NUMBER")]
        public int Number { get; set; }
    }
    

    2) 您也可以使用 InversePropertyAttribute。

    [Table("WIDGETENTITIES")]
    public class WidgetEntity {
    
        [Column("WIDGETENTITY_ID")]
        public int Id { get; set; }
    
        [InverseProperty("WidgetEntities")]
        public WidgetSequence Sequence { get; set; }
    
        // and other properties that map correctly
    }
    
    [Table("WIDGETSEQUENCES")]
    public class WidgetSequence { 
    
        [Column("WIDGETSEQUENCE_ID")]
        public int Id { get; set; }
    
        [Column("NUMBER")]
        public int Number { get; set; }
    
        public virtual List<WidgetEntity> WidgetEntities { get; set; }
    }
    

    【讨论】:

    • 谢谢!文档和其他一些 SO 答案表明,可以在反向属性真正应该使用的地方使用外键属性。
    • @Carl,你发现的那些建议不是正确的方法。 FK 属性位于列上方,而不是 inverse 属性。
    • @RichardPierre 感谢您的回复。但是,除了具有 InverseProperty 的 Id 列之外,我无法引用另一列。这个问题怎么办?它有什么问题? stackoverflow.com/questions/29327772/…
    • > [ForeignKey("WidgetSequenceId")] //必须是属性名,不能是表列名 -------------------- ------------------------------------------ 这甚至不是属性名称它是 Id---------------------------------------------------------- 1.2 还是不是属性名...!?
    • 这是一个更好的答案,应该标记为 imo,因为 OP 已经在使用数据注释
    【解决方案2】:

    ForeignKey attibute 期望您的类中的属性名称作为参数,但您给出了列名称。使用流畅的映射。

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    
        modelBuilder.Entity<WidgetEntity>()
         .HasRequired(w => w.Sequence)
         .WithMany()
         .Map(m => m.MapKey("WIDGETSEQUENCE_ID"));
    }
    

    【讨论】:

    【解决方案3】:

    有一个名为 Users 的表,它有一个名为 UserID 的主键。

    还有一个名为 Directory 的表,它有一个名为 UserID 的列,它被定义为用户表的外键。

    我可以像这样使用 ForeignKey 注释来映射外键:

    [ForeignKey("xyzzy")]
    public int? UserID { get; set; }  // This is a column in the table
    public virtual User xyzzy { get; set; } // This is my instance of User
    

    【讨论】:

      猜你喜欢
      • 2018-08-13
      • 2017-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-25
      • 1970-01-01
      相关资源
      最近更新 更多