Entity framework 实体框架代码优先:同一表的一对多和多对多关系

Entity framework 实体框架代码优先:同一表的一对多和多对多关系,entity-framework,ef-code-first,code-first,entity-framework-migrations,Entity Framework,Ef Code First,Code First,Entity Framework Migrations,我的项目中有一个用户模型和一个事件模型。事件具有创建者(用户)和参与者(用户),因此事件与用户之间存在一对多关系,与同一个表之间也存在多对多关系 我第一次有这样的一对多关系: Public class Event { ... public int CreatedById { get; set; } public virtual User CreatedBy { get; set; } ... } 然后,当我添加多对多关系时,迁移不会生成多对多关系

我的项目中有一个用户模型和一个事件模型。事件具有创建者(用户)和参与者(用户),因此事件与用户之间存在一对多关系,与同一个表之间也存在多对多关系

我第一次有这样的一对多关系:

Public class Event
{
      ...
      public int CreatedById { get; set; }
      public virtual User CreatedBy { get; set; }
      ...
}
然后,当我添加多对多关系时,迁移不会生成多对多关系:

Public class User
{
      ...
      public virtual ICollection<Event> Events { get; set; }
      ...
}

Public class Event
{
      ...
      public int CreatedById { get; set; }
      public virtual User CreatedBy { get; set; }
      public virtual ICollection<User> Users { get; set; }
      ...
}
公共类用户
{
...
公共虚拟ICollection事件{get;set;}
...
}
公开课活动
{
...
public int CreatedById{get;set;}
公共虚拟用户通过{get;set;}创建
公共虚拟ICollection用户{get;set;}
...
}
如果我删除了一对多关系,那么迁移将成功生成多对多关系


有没有一种方法可以只使用数据注释来实现这一点?

EF不知道用户的位置。事件必须映射到哪里。它可以是
Event.CreatedBy
,也可以是
Event.Users
。两者都将产生一个有效的模型。您必须通过应用
[InverseProperty]
属性给EF一点提示:

public class User
{
    ...
    [InverseProperty("Users")]
    public virtual ICollection<Event> Events { get; set; }
    ...
}
公共类用户
{
...
[反向属性(“用户”)]
公共虚拟ICollection事件{get;set;}
...
}

对于代码优先的方法,我总是建议使用fluent API,而不是使用DataAnnotation,后者会自动使用一些转换

通过这种方式,您将知道所做的确切配置

如果我是你,我会用以下方法:

public class EventMap : EntityTypeConfiguration<Event>
{
    public EventMap()
    {
        this.HasRequired(m => m.CreatedBy) // envent must have a creator
            .WithMany() // a user can have 0,1 or more events created by him
            .HasForeignKey(m => m.CreatedById) // specify property to be used as FK
            .WillCascadeOnDelete(true); // delete all events created by user if that specific user is deleted

        this.HasMany(m=>m.Users) // an event can have 0,1 or more participants
            .WithMany(m=>m.Events) // a user can be a participant in 0,1 or more events                
            .Map(m => m.MapLeftKey("EventId").MapRightKey("UserId")); // this will generate intermediate table to hold participant information - dbo.EventUser with EventId & UserId
            // Cascade Delete is always true for Many to Many mapping. however, it doesn't delete entry in other table, it deletes entry in Joined Table only.
    }
}
公共类事件映射:EntityTypeConfiguration
{
公共事件地图()
{
this.HasRequired(m=>m.CreatedBy)//envent必须有一个创建者
.WithMany()//用户可以创建0,1个或多个事件
.HasForeignKey(m=>m.CreatedById)//指定要用作FK的属性
.WillCascadeOnDelete(true);//如果删除了该特定用户,则删除该用户创建的所有事件
this.HasMany(m=>m.Users)//一个事件可以有0,1个或更多参与者
.WithMany(m=>m.Events)//用户可以是0,1个或更多事件的参与者
.Map(m=>m.MapLeftKey(“EventId”).MapRightKey(“UserId”);//这将生成中间表来保存参与者信息-dbo.EventUser和EventId&UserId
//级联删除对于多对多映射总是正确的。但是,它不会删除其他表中的条目,它只删除联接表中的条目。
}
}

你说得对@slauma,请原谅我的英语不是我的母语,我只是尽力了。我编辑了它,希望更清楚我不是指语言,而是指内容(如果有任何错误消息或异常,等等,或者如果结果不是你期望的,等等)。不管怎样,不管怎样,问题似乎已经解决了:)