2

我正在尝试创建一个数据库,其中一个表具有一对一关系和多对多关系......创建的数据库似乎仅作为一对一关系工作。这是我的模型:

public class Trip
    {
        public int ID { get; set; }
        public virtual ICollection<Place> PassingBy { get; set; }
        public Place Origin { get; set; }
        public Place Destination { get; set; }
        public DateTime Time { get; set; }
        public int EmptySlots { get; set; }
        public virtual ICollection<Person> Attendants { get; set; }
        public string AccessKey { get; set; }

    }

    public class Person
    {
        public int ID { get; set; }
        public string Username { get; set; }
        public virtual ICollection<Trip> Trips { get; set; }
    }

    public class Place
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public virtual ICollection<Trip> Trips { get; set; }
    }


    public class GARDB : DbContext
    {
        public DbSet<Trip> Trips { get; set; }
        public DbSet<Person> Persons { get; set; }
        public DbSet<Place> Places { get; set; }
    }

现在,当我进行添加迁移和更新数据库时。该数据库有一个名为“PersonTrip”的表,它是多对多关系所必需的。但是“PlaceTrip”没有表格。经过一些试验和错误。我发现这是因为这些行:

    public Place Origin { get; set; }
    public Place Destination { get; set; }

它们导致关系是一对多的。不是我想成为的多对多。有没有办法让 Place-Trip 关系像 Person-Trip 一样,但不删除那两条线。

谢谢!

编辑:解决方案

我没有说清楚我想要什么。我想画线

public virtual ICollection<Place> PassingBy { get; set; }

映射到线

public virtual ICollection<Trip> Trips { get; set; }

在 Place 类中。我从答案中得到的解决方案是:

代替 :

 public virtual ICollection<Place> PassingBy { get; set; }

和:

[InverseProperty("Trips")]
public virtual ICollection<Place> PassingBy { get; set; }

并替换:

public virtual ICollection<Trip> Trips { get; set; }

在 Place 类中:

[InverseProperty("PassingBy")]
public virtual ICollection<Trip> Trips { get; set; }

并在顶部添加此包含:

using System.ComponentModel.DataAnnotations.Schema;
4

2 回答 2

1

实际上,令人困惑的是,您在 Trip 上的关系有两个目的:

public Place Origin { get; set; }
public Place Destination { get; set; }

(这也应该是虚拟的,顺便说一句),并且只有一个地方:

public virtual ICollection<Trip> Trips { get; set; }

...所以实体框架无法弄清楚哪个与什么相配。

您需要向 Place 添加第二个导航属性和一些数据注释属性,以告诉 Entity Framework 它们如何关联以形成多对多关系的两半。为了清楚起见,省略了其他属性和上下文,如下所示:

public class Trip
{
    [InverseProperty ("AsOrigin")]
    public virtual Place Origin { get; set; }

    [InverseProperty ("AsDestination")]
    public virtual Place Destination { get; set; }
}

public class Place
{
    [InverseProperty ("Origin")]
    public virtual ICollection<Trip> AsOrigin { get; set; }

    [InverseProperty ("Destination")]
    public virtual ICollection<Trip> AsDestination { get; set; }
}

如果您需要 Place 上的单个属性来为您提供它所涉及的所有旅行,无论是作为起点还是终点,您可以使用如下导航属性重新创建它:

[NotMapped]
public ICollection<Trip> Trips
{
    get
    {
        return AsOrigin.Concat(AsDestination).Distinct();
    }
}
于 2013-03-19T14:55:59.737 回答
0

我不是您在这里创建的关系的忠实拥护者,但这是您的 DBA 需要考虑的事情。与此同时,如果你想做这样的事情,我可以建议利用这个 SO question的答案,它试图做一些非常相似的事情。您需要添加更多属性并在表之间设置外键关系,但它应该可以正常工作。

于 2013-03-19T13:27:51.100 回答