Entity Framework:与 Fluent API 的三向多对一关系?

Entity Framework: three way many-many-one relationship with Fluent API?

试图围绕这种关系思考并弄清楚如何用流利的方式映射它 api。

我有三个对象;请求、响应和管理员

一个请求可以有多个响应,来自一个或多个管理员

一个响应可以与一个请求和一个管理员相关联。

管理员可以与许多响应和许多请求相关联

从逻辑上讲,管理员被分配到一个请求,并且可以创建与他们被分配到的请求相关联的响应。我意识到架构明智的管理员可以创建对他们未分配给的请求的响应,但这在应用程序中作为业务规则强制执行,除非有一种干净的方式来强制执行我并不真正关心的架构。

到目前为止我看到的是以下(简化的)对象:

要求:

public class Request {
    public Guid Id {get;set;}
    public virtual ICollection<Response> Responses {get;set;}
    public virtual ICollection<Administrator> Administrators {get;set;}
}

回复:

public class Response {
    public Guid Id {get;set;} 
    public virtual Request { get;set;}
    public virtual Administrator { get;set;}
}

管理员:

public class Administrator {
   public Guid Id {get;set;}
   public virtual ICollection<Request> Requests {get;set;}
   public virtual ICollection<Response> Responses {get;set;}
}

我觉得这比我想象的要简单。但是,如果有人可以帮助我为此翻译流畅的 api 映射,那就太好了! :)

编辑:

一直在摆弄这个,我想我可能已经确定了一个解决方案:

响应有两个必需的请求和管理员映射

public class Response: EntityTypeConfiguration<Response>
{
    public ResponseMap()
    {

        HasKey(response => response.Id);

        HasRequired(e => e.Request);
        HasRequired(e => e.Administrator);
    }
}

请求具有多对一响应和多对多管理员关系 table:

public class RequestMap : EntityTypeConfiguration<Request>
{
    public RequestMap()
    {

        HasKey(r => r.Id);

        HasMany(e => e.Responses)
            .WithRequired(e => e.Request)
            .WillCascadeOnDelete(false);

        HasMany(or => or.Administrators)
            .WithMany(p => p.Requests)
            .Map(mc =>
            {
                mc.ToTable("RequestAdministrator");
                mc.MapLeftKey("RequestId");
                mc.MapRightKey("AdministratorId");
            });


    }
}

并且管理员与响应具有多对一关系。它也与请求有关系,但在上面的映射中定义。

public class AdministratorMap : EntityTypeConfiguration<Administrator>
{
    public AdministratorMap()
    {
        HasKey(e => e.Id);

        HasMany(p => p.Responses)
            .WithRequired(o => o.Administrator)
            .WillCascadeOnDelete(false);

    }
}

我不是 100% 确定这是正确的方法,但乍一看似乎很合适。

我用下面的代码用这个数据库图生成了一个数据库:

class Program
{
    static void Main(string[] args)
    {
        Context context = new Context();
        context.Database.Initialize(true);
    }
}

public class Request
{
    public int RequestId { get; set; }
    public virtual ICollection<Response> Responses { get; set; }
    public virtual ICollection<Administrator> Administrators { get; set; }
}

public class Response
{
    public int ResponseId { get; set; }
    public virtual Request Request { get; set; }
    public virtual Administrator Administrator { get; set; }
}

public class Administrator
{
    public int AdministratorId { get; set; }
    public virtual ICollection<Request> Requests { get; set; }
    public virtual ICollection<Response> Responses { get; set; }
}

public class Context : DbContext
{
    public Context()
    {
        Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
    }

    public DbSet<Request> Requests { get; set; }
    public DbSet<Response> Responses { get; set; }
    public DbSet<Administrator> Administrators { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Configurations.Add(new RequestsConfig());
        modelBuilder.Configurations.Add(new AdministratorsConfig());
        base.OnModelCreating(modelBuilder);
    }
}

public class RequestsConfig : EntityTypeConfiguration<Request>
{
    public RequestsConfig()
    {
        HasMany(r => r.Responses).WithRequired(rs => rs.Request);
        HasMany(r => r.Administrators).WithMany(a => a.Requests);
    }
}

public class AdministratorsConfig: EntityTypeConfiguration<Administrator>
{
    public AdministratorsConfig()
    {
        HasMany(a => a.Responses).WithRequired(r => r.Administrator);
    }
}
public class Request
{
  public int RequestId { get; set; }
  public virtual ICollection<Response> Responses { get; set; }
  public virtual ICollection<Administrator> Administrators { get; set; }
}

public class Response
{
public int ResponseId { get; set; }
[ForeignKey("Request")]
public virtual int? RequestID {get;set;}
public virtual Request Request{get;set;}
[ForeignKey("Administrator ")]
public virtual int? AdministratorID {get;set;}
public virtual Administrator Administrator { get; set; }
}

public class Administrator
{
public int AdministratorId { get; set; }
public virtual ICollection<Request> Requests { get; set; }
public virtual ICollection<Response> Responses { get; set; }
}
This is what you want

[Table("REQUEST", Schema = "YourSchema")]
public class REQUEST
{

    public REQUEST()
    {
        Responses = new HashSet<RESPONSE>();
        Administrators = new HashSet<ADMINISTRATOR>();
    }

    [Column("REQUESTID")]
    public int RequestId { get; set; }

    public virtual ICollection<RESPONSE> Responses { get; set; }
    public virtual ICollection<ADMINISTRATOR> Administrators { get; set; }
}

[Table("RESPONSE", Schema = "YourSchema")]
public class RESPONSE
{
    [Column("RESPONSEID")]
    public int ResponseId { get; set; }

    [Column("REQUESTID")]
    public int RequestId { get; set; }

    [Column("ADMINISTRATORID")]
    public int AdministratorId { get; set; }

    [ForeignKey("RequestId")]
    public virtual REQUEST Request { get; set; }

    [ForeignKey("AdministratorId")]
    public virtual ADMINISTRATOR Administrator { get; set; }
}

[Table("ADMINISTRATOR", Schema = "YourSchema")]
public class ADMINISTRATOR
{
    public ADMINISTRATOR()
    {
        Requests = new HashSet<REQUEST>();
        Responses = new HashSet<RESPONSE>();
    }
    [Column("ADMINISTRATORID")]
    public int AdministratorId { get; set; }

    public virtual ICollection<REQUEST> Requests { get; set; }
    public virtual ICollection<RESPONSE> Responses { get; set; }
}

    public DbSet<REQUEST> Requests { get; set; }
    public DbSet<RESPONSE> Responses { get; set; }
    public DbSet<ADMINISTRATOR> Administrators { get; set; }

我相信您采用了正确的方法,将集合用于每个请求和响应(多对多关系)的模型。考虑将多对一关系应用于单独的部分 class 以增加粒度和关注点分离。

namespace ManyToManyToOneMessage
{
    public partial class Message 
    {
        public Guid Id { get; set; }
        public virtual ICollection<Response> Responses { get; set; }
        public virtual ICollection<Administrator> Administrators { get; set; }
    }

    public partial class Message
    {
        public Request Request {get; set;}
        public Administrator Administrator { get; set;}
    }

    public class Response
    {
        //Place response formatting here.
    }

    public class Request
    {
        //Place request formatting here.
    }

    public class Administrator  {
        public Guid Id { get; set; }
        public virtual ICollection<Request> Requests { get; set; }
        public virtual ICollection<Response> Responses { get; set; }
    }   
}

这只是一条消息,包含请求和响应。