实体框架:与Fluent API有三种多对多的关系?

时间:2016-05-24 14:13:34

标签: c# entity-framework ef-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);
    }
}

请求具有多对一的响应,多对多的管理员具有关系表:

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%确定这是正确的方法,但乍一看似乎是合适的。

4 个答案:

答案 0 :(得分:1)

我使用以下代码生成一个包含此数据库图表的数据库:

Database Diagram

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);
    }
}

答案 1 :(得分:0)

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; }
}

答案 2 :(得分:0)

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; }

答案 3 :(得分:0)

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

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; }
    }   
}

这仅适用于一条带有请求和响应的消息。