使用实体框架在一个表中的2个外键

时间:2014-11-01 19:25:51

标签: entity-framework

我有三个班级

Event, Dog, Result

每只狗都可以参加许多活动,每次活动都会获得与此特定活动相关的分数。 因此必须意味着我的结果类必须包含2个外键。 1表示事件,1表示狗。我很困惑如何设置它。我早些时候得到了这方面的帮助,我希望有人可以再次帮助我:

以下是我的课程:

公共类狗     {

    public int DogId { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public bool Checked { get; set; }
    public string DogImage { get; set; }

    [ForeignKey("Event")]
    public int EventID { get; set; }


    public virtual ICollection<Result> Results { get; set; }

    public virtual Event Event { get; set; }
}

public class Event
    {
        public int EventId { get; set; }
        public string EventName { get; set; }
        public string EventLocation { get; set; }
        public string EventType { get; set; }
        public string EventDate { get; set; } 

        public virtual ICollection<Dog> Dogs { get; set; }
    }

 public class Result
    {
        public int ResultId { get; set; }
        public int Track { get; set; }
        public int Obedience { get; set; }
        public int Protection { get; set; }

        [ForeignKey("Dog")]
        public int DogId { get; set; }

        public virtual Dog Dog { get; set; }
    }

帮助表示感谢,谢谢!

编辑:

好的,这就是它现在的样子。我应该说,当我尝试使用这些更新进行mgration时,我收到了一个错误,结尾为:may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

我在dbcontext中添加了这个方法,它处理了这个问题(我想......)

public class EfdbContext : DbContext
{
    public DbSet<Event> Events { get; set; }
    public DbSet<Dog> Dogs { get; set; }
    public DbSet<Result> Results { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Event>()
    .HasRequired(c => c.Results)
    .WithMany()
    .WillCascadeOnDelete(false);
} 

现在,当我尝试迁移时,我收到此错误:

  

ALTER TABLE语句与FOREIGN KEY约束“FK_dbo.Events_dbo.Results_Results_ResultId”冲突。冲突发生在数据库“CloudDog.EFDB.EfdbContext”,表“dbo.Results”,列'ResultId'中。   这就是我的课程现在的样子:

public class Event
{
    public int EventId { get; set; }
    public string EventName { get; set; }
    public string EventLocation { get; set; }
    public string EventType { get; set; } //Dropdown med tävlingar
    public string EventDate { get; set; } //Picker

    public virtual ICollection<Dog> Dogs { get; set; }
    public virtual ICollection<Result> Results { get; set; }
}

public class Dog
{
    public int DogId { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public bool Checked { get; set; }
    public string DogImage { get; set; }

    [ForeignKey("Event")]
    public int EventId { get; set; }

    public virtual ICollection<Merit> Merits { get; set; }
    public virtual ICollection<Result> Results { get; set; }

    public virtual Event Event { get; set; }
}

 public class Result
{
    public int ResultId { get; set; }
    public int Track { get; set; }
    public int Obedience { get; set; }
    public int Protection { get; set; }

    [ForeignKey("Dog")]
    public int DogId { get; set; }
    public virtual Dog Dog { get; set; }

    [ForeignKey("Event")]
    public int EventId { get; set; }      
    public virtual Event Event { get; set; }
}

2 个答案:

答案 0 :(得分:2)

在你的previous question中,你没有讲述整个故事。解决方案本身就是正确的。如果只有 两个类之间的多对多关联,那么EF可以通过在类模型中保持不可见的联结表来对其进行建模。

但现在您向此联结表添加更多信息。这意味着表必须在类模型中表示为类,否则您将永远无法访问此信息。现在你的模型应该是这样的(简化为要点):

public class Dog
{
    public int DogId { get; set; }
    public virtual ICollection<Result> Results { get; set; }
}

public class Event
{
    public int EventId { get; set; }
    public virtual ICollection<Result> Results { get; set; }
}

public class Result
{
    public int ResultId { get; set; }

    [ForeignKey("Dog")]
    public int DogId { get; set; }
    public virtual Dog Dog { get; set; }

    [ForeignKey("Event")]
    public int EventId { get; set; }
    public virtual Dog Event { get; set; }
}

逻辑上,DogEvent之间仍然存在多对多关联,但技术上它实现为1-n-1关联。因此,通过添加信息,您可以牺牲从DogEvent的快捷访问权限。这很常见。我经常看不到纯粹的多对多关联。人们迟早会开始存储关于关联的信息。

现在,如果您想要获取Dog的{​​{1}} s,则必须编写一个更复杂的查询:

Event

答案 1 :(得分:1)

“结果”类是结合表,它体现了狗与事件之间的多对多关系。所以Dog上的Dogs属性和Dog上的Events属性应该是结果的ICollection。 Result类实际上是DogInEvent类。