实体框架代码1st-映射多对多信息 [英] Entity Framework Code 1st - Mapping many-to-many with extra info

查看:88
本文介绍了实体框架代码1st-映射多对多信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看过这里的几个问题,并且还没有完全将所有(心理)点联系起来.我会感谢您的帮助.

I've looked through several of the questions here and am not quite connecting all the (mental) dots on this. I would appreciate some help.

我的模型(代码优先):

My Models (code first):

public class cgArmorial
{
    [Key]
    [Display(Name = "Armorial ID")]
    public Guid ArmorialID { get; set; }
    [Display(Name = "User ID")]
    public Guid UserId { get; set; }
    public string Name { get; set; }
    public string DeviceUrl { get; set; }
    public string Blazon { get; set; }

    public virtual ICollection<cgArmorialAward> ArmorialAwards { get; set; }
}

public class cgArmorialAward
{
    public cgArmorial Armorial { get; set; }
    public cgAward Award { get; set; }
    public DateTime AwardedOn { get; set; }
}
public class cgAward
{
    [Key]
    [Display(Name = "Award ID")]
    public Guid AwardID { get; set; }
    public string Name { get; set; }
    public string Group { get; set; }
    public string Description { get; set; }
    public string ImageUrl { get; set; }
    public string Blazon { get; set; }

    public virtual ICollection<cgArmorialAward> ArmorialAwards { get; set; }
}

然后在我的Context类中(最后2个条目):

Then in my Context class I have (last 2 entries):

public class Context : DbContext
{
    public DbSet<cgUser> Users { get; set; }
    public DbSet<cgEvent> Events { get; set; }
    public DbSet<cgEventType> EventTypes { get; set; }
    public DbSet<cgArmorial> Armorials { get; set; }
    public DbSet<cgAward> Awards { get; set; }
    public DbSet<cgArmorialAward> ArmorialAwards { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<cgUser>()
                    .HasMany<cgEvent>(e => e.EventAutocrats)
                    .WithMany(u => u.EventAutocrats)
                    .Map(m =>
                    {
                        m.ToTable("EventAutocrats");
                        m.MapLeftKey("UserId");
                        m.MapRightKey("EventId");
                    });
        modelBuilder.Entity<cgUser>()
                    .HasMany<cgEvent>(e => e.EventStaff)
                    .WithMany(u => u.EventStaff)
                    .Map(m =>
                    {
                        m.ToTable("EventStaff");
                        m.MapLeftKey("UserId");
                        m.MapRightKey("EventId");
                    });
        modelBuilder.Entity<cgArmorialAward>()
                    .HasRequired(a => a.Armorial)
                    .WithMany(b => b.ArmorialAwards);
        modelBuilder.Entity<cgArmorialAward>()
                    .HasRequired(a => a.Award)
                    .WithMany();    // b => b.ArmorialAwards
    }
}

尝试运行时出现此错误:

I am getting this error when I try to run:

System.Data.Edm.EdmEntityType::EntityType'cgArmorialAward'没有 定义的键.定义此EntityType的键. System.Data.Edm.EdmEntitySet:EntityType:EntitySet``Armorial奖励''. 基于未定义密钥的cgArmorialAward类型.

System.Data.Edm.EdmEntityType: : EntityType 'cgArmorialAward' has no key defined. Define the key for this EntityType. System.Data.Edm.EdmEntitySet: EntityType: EntitySet �ArmorialAwards� is based on type �cgArmorialAward� that has no keys defined.

推荐答案

好吧,正如例外所示:您没有在实体cgArmorialAward上定义键.每个实体都必须有一个密钥.将其更改为以下内容:

Well, as the exception says: You don't have a key defined on your entity cgArmorialAward. Every entity must have a key. Change it to the following:

public class cgArmorialAward
{
    [Key, Column(Order = 0)]
    [ForeignKey("Armorial")]
    public Guid ArmorialID { get; set; }

    [Key, Column(Order = 1)]
    [ForeignKey("Award")]
    public Guid AwardID { get; set; }

    public cgArmorial Armorial { get; set; }
    public cgAward Award { get; set; }
    public DateTime AwardedOn { get; set; }
}

复合键中的字段是同时指向其他两个表的外键,因此是ForeignKey属性. (我不确定约定是否会自动检测到此内容,因为您使用的是非标准名称(类为"cgXXX",外键属性为"XXXId").另一方面,属性名称为Armorial匹配外键属性名称.我不确定EF约定是否会考虑这一点.因此,也许ForeignKey属性不是必需的,但至少没有错.)

The fields in the composite key are foreign keys to the other two tables at the same time, hence the ForeignKey attribute. (I'm not sure if conventions would detect this automatically because you have non-standard names ("cgXXX" for the classes and "XXXId" for the foreign key properties). On the other hand the property names Armorial and Award match the foreign key property names. I'm not sure if EF conventions would consider this. So, perhaps the ForeignKey attribute is not necessary but at least it's not wrong.)

这篇关于实体框架代码1st-映射多对多信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆