在代码第一实体框架中定义多对多关系

时间:2013-03-10 21:39:22

标签: c# entity-framework ef-code-first ef-migrations

我的模型中有3个课程,如下所示。

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public string UserName { get; set; }

    public ICollection<MartialArtUserProfile> MartialArtUserProfiles { get; set; }
}

[Table("MartialArt")]
public class MartialArt
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }

    public string IconPath { get; set; }

    public string ImagePath { get; set; }

    public ICollection<MartialArtUserProfile> MartialArtUserProfiles { get; set; }
}

public class MartialArtUserProfile
{
    public int UserProfileId { get; set; }
    public UserProfile UserProfile { get; set; }

    public int MartialArtId { get; set; }
    public MartialArt MartialArt { get; set; }
}

我有一个多对多关系的配置类,如下所示:

public class MartialArtUserProfileConfiguration : EntityTypeConfiguration<MartialArtUserProfile>
{
    public MartialArtUserProfileConfiguration()
    {
        HasKey(a => new { a.MartialArtId, a.UserProfileId });

        HasRequired(a => a.MartialArt)
            .WithMany(s => s.MartialArtUserProfiles)
            .HasForeignKey(a => a.MartialArtId)
            .WillCascadeOnDelete(false);

        HasRequired(a => a.UserProfile)
            .WithMany(p => p.MartialArtUserProfiles)
            .HasForeignKey(a => a.UserProfileId)
            .WillCascadeOnDelete(false);
    }
}

在我尝试在程序包管理器控制台中运行更新数据库时,为我的实体定义关系后,它说:

  

在模型生成期间检测到一个或多个验证错误:

     

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

我做错了什么?

提前致谢,

3 个答案:

答案 0 :(得分:8)

如果我理解你只是想用一个传递表来创建多对多。如果是这样,这是另一种方法。使用Fluent API进行如下映射。您可以将UserProfileToMartialArt更改为您希望表名称的任何内容。而不是创建MartialArtUserProfile模型让EF为您创造中间地带。这也指定了可以解决错误的键。

modelBuilder.Entity<UserProfile>()
    .HasMany(b => b.MartialArts)
    .WithMany(a => a.UserProfiles)
    .Map(m => m.MapLeftKey("MartialArtId")
        .MapRightKey("UserProfileId")
        .ToTable("UserProfileToMartialArt"));

在MartialArts模型中

public IList<UserProfile> UserProfiles { get; set; }   

在UserProfile Model中输入

public IList<MartialArt> MartialArts { get; set; }  

答案 1 :(得分:7)

尝试这样做:

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public string UserName { get; set; }

    [InverseProperty("UserProfiles")]
    public IList<MartialArt> MartialArts { get; set; }
}

[Table("MartialArt")]
public class MartialArt
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }

    public string IconPath { get; set; }

    public string ImagePath { get; set; }

    [InverseProperty("MartialArts")]
    public IList<UserProfile> UserProfiles { get; set; }
}

答案 2 :(得分:6)

在EntityFramework 6.1中,您不需要执行任何操作 - 只需将两种类型的集合添加到每个类中,一切就绪。

public class UserProfile {
    public int Id { get; set; }
    public string UserName { get; set; }
    public virtual ICollection<MartialArt> MartialArts { get; set; }

    public UserProfile() {
        MartialArts = new List<MartialArt>();
    }
}

public class MartialArt {
    public int Id { get; set; }
    public string Name { get; set; }
    // *snip*
    public virtual ICollection<UserProfile> UserProfiles { get; set; }

    public MartialArt() {
        UserProfiles = new List<UserProfile>();
    }
}