【问题标题】:How do I make a Code-First Entity Framework 4.3 Many-To-Many table with additional columns?如何制作带有附加列的 Code-First Entity Framework 4.3 多对多表?
【发布时间】:2012-05-22 18:01:49
【问题描述】:

我在 MVC3 的实体框架 4.3 代码优先模型中有以下类:

public class Film
{
    public Int32 ID { get; set; }

    [Column("FilmName"), MinLength(2), MaxLength(100)]
    [Required(ErrorMessage = "Please enter a name")]
    public String Name { get; set; }

    public Model.Cast Cast { get; set; }
}

public class Actor
{
    public Int32 ID { get; set; }

    [MaxLength(75)]
    public String Name { get; set; }
}

[Table("Cast")]
public class Cast
{
    public Actor Actor { get; set; }

    [MaxLength(500)]
    public String Role { get; set; }

    public virtual Film Film { get; set; }
}

我想要一个如下的表格布局:

Films:
ID PK
Name

Cast:
FilmID PK FK
ActorID PK FK
Role

Actors:
ID PK
Name

如何创建 Cast 表?我现在收到以下错误:

##System.Data.Entity.Edm.EdmEntityType: : EntityType 'Cast' 没有定义键。定义此 EntityType 的键。 \tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'Casts' 基于没有定义键的类型'Cast'。##

但是我不想创建 ID 键,我想使用 Film 和 Actor 的 ID 字段来做一个复合主键,它们都是其他表的外键。

我该怎么办?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 entity-framework entity-framework-4 many-to-many


    【解决方案1】:

    您必须以这种方式重新定义您的模型:

    public class Film
    {
        public Int32 ID { get; set; }
    
        [Column("FilmName"), MinLength(2), MaxLength(100)]
        [Required(ErrorMessage = "Please enter a name")]
        public String Name { get; set; }
    
        public ICollection<Model.Cast> Cast { get; set; }
    }
    
    public class Actor
    {
        public Int32 ID { get; set; }
    
        [MaxLength(75)]
        public String Name { get; set; }
    
    
        public ICollection<Model.Cast> Cast { get; set; }
    }
    
    [Table("Cast")]
    public class Cast
    {
        [Key, Column(Order = 0)]
        public int ActorId { get; set; }
        [Key, Column(Order = 1)]
        public int FilmId { get; set; }
    
        [MaxLength(500)]
        public String Role { get; set; }
    
        [ForeignKey("ActorId")]
        public Actor Actor { get; set; }
        [ForeignKey("FilmId")]
        public virtual Film Film { get; set; }
    }
    

    【讨论】:

    • 太棒了,非常感谢。我实际上已经尝试过这种方法,但我没有在 Actor 类中包含public ICollection&lt;Model.Cast&gt; Cast { get; set; }。非常感谢。
    • public ICollection&lt;Model.Cast&gt; Cast { get; set; } 是虚拟的吗?
    • 是的,如果您想使用延迟加载,请将其设为虚拟。
    【解决方案2】:

    我之前尝试过这样做,但没有成功。我的解决方案是将链接表映射为具有自己身份 PK 的普通实体,并自定义 DatabaseInitializer 以运行 DDL 脚本来为 FK 创建唯一索引。我猜 EF 的设计初衷不是支持这种遗留映射。

    【讨论】:

    • IT 不是传统映射,它是标准化数据库的一种完全有效的方法。值得庆幸的是,有一个解决方案,因为以这种方式建模很重要。
    • 也许我表达得不好……例如,大多数 OODMBS 要求每个表都有自己的唯一键,单个字段作为每行(对象)的唯一标识符。由于我们使用 ORM 将关系数据库映射到应用程序的域/模型对象,因此在我们如何创建数据库表以及如何创建表示该表的类方面总是存在着名的不匹配阻抗。出于这个原因,我称之为遗留映射,没有冒犯。有时以更接近我们的类的方式在 DB 中创建表更容易,只是为了简化映射。明天或更晚,EF 可能会发生变化。
    猜你喜欢
    • 2011-07-22
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    • 2011-04-06
    相关资源
    最近更新 更多