我需要一些帮助。基于我对项目的想法,我在创建模型时遇到了重大问题。为简化起见,我有一个Parent表,一个Student表和一个Address表。因此,每个父记录,可以有多个学生,只有一个地址。每个学生记录,可以有多个父母,只有一个地址。从逻辑上讲,我真的不能认为学生的地址与父母的地址相同,因为可能有一个学生的父母住在不同的地方。所以,我希望能够为学生提供一个地址以及每个家长的地址。所以,我基本上设想这个数据库布局下到一个地址表,包括AddressID,street,city,state,zip ..然后是一个学生表,带有StudentID,name,addressID。然后是具有ParentID,name,addressID的Parent表。然后是Parent_Student引用表,带有StudentID和ParentID。
那么,关于如何实现这一点的任何想法?我只用地址信息和ID创建了我的地址模型。我使用ID,名称,虚拟地址和虚拟ICollection Parent创建了我的学生模型。然后使用ID,名称,虚拟地址和虚拟ICollection创建我的父模型。当我尝试通过New-> Scaffolded Item创建我的学生控制器时,我收到一个关于VS的错误,无法确定父类和地址类型之间关联的主要结束。
我认为这与地址记录对父母或学生都有外键的事实有关,但不是两者都有。我对这整个代码优先的方法很陌生,所以任何洞察都会非常感激。提前谢谢!
编辑:添加更新的代码
PERSON模特:
public enum PersonType
{
Student, Parent, Teacher
}
public abstract class Person
{
[Key]
public int PersonId { get; set; }
[Required]
[StringLength(50,ErrorMessage = "First Name cannot be longer than 50 characters.")]
[Display(Name= "First Name")]
public string FirstName { get; set; }
[StringLength(50, ErrorMessage = "Middle Name cannot be longer than 50 characters.")]
[Display(Name = "Middle Name")]
public string MiddleName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "Last Name cannot be longer than 50 characters.")]
[Display(Name = "Last Name")]
public string LastName { get; set; }
public PersonType personType {get; set;}
public Address Address { get; set; }
[Display(Name = "Full Name")]
public string FullName
{
get
{
return FirstName + " " + LastName;
}
}
[Display(Name = "Full Name w Middle")]
public string FullNameWMid
{
get
{
return FirstName + " " + MiddleName + " " + LastName;
}
}
}
学生模特:
public class Student : Person
{
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:mm-dd-yyyy}", ApplyFormatInEditMode = true)]
[Display(Name = "Birthday")]
public DateTime Birthday { get; set; }
public ICollection<int> ParentList { get; set; }
public virtual ICollection<Parent> Parents { get; set; }
public virtual Teacher Teacher { get; set; }
}
父模型:
public class Parent : Person
{
public string EmailAddress { get; set; }
public ICollection<int> StudentList { get; set; }
public virtual ICollection<PhoneNumber> PhoneNumbers { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
地址模型:
public class Address
{
public int AddressId { get; set; }
public string StreetLine1 { get; set; }
public string StreetLine2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public Person Person { get; set; }
}
答案 0 :(得分:1)
是的,你在这里会遇到很多问题。首先,实体框架在使用&#34;共享主键&#34;时仅支持1:1关系。这意味着地址ID和父或学生ID必须相同,并且地址必须是另一个的外键。
我知道为每个创建导航属性似乎很容易,你应该有1:1,但你必须考虑如何在数据库中创建它。它实际创造的是两个独立的1:多种关系。并且,由于没有什么可以阻止您将多个实体分配给多端,这导致EF不支持的情况。
这当然会让事情变得困难,因为你有几个表来链接地址。
我建议改为创建一个&#34; Person&#34; Student和Parent派生自的实体,然后使用TPH或TPC继承来创建Student和Parent唯一实体。
这允许您的家长和学生共享一个公共ID,然后您可以将其用作与您的地址实体的1:1共享密钥。
您可以在此处找到更多信息:
http://blog.bennymichielsen.be/2011/06/02/entity-framework-4-1-one-to-one-mapping/
答案 1 :(得分:0)
首先,我不认为命名是合适的。将父母与学生联系没有任何意义,我认为应该是父母和孩子。并且在每个属性中提供ID属性作为主键使得维护非常困难。但是,让我们尝试按照您的方式实施它。
将一个类作为具有共同属性的人,如ID,全名和名字和姓氏,门牌号码等其他一般信息。这样做会给出一个主键(ID)和一个外键(门牌号)。现在你与Address类有1:1的关系。
在上面给出的学生和家长课程模型中,我发现没有这样的属性可以将学生与其父母相关联,反之亦然。现在您创建类Parent和Student,例如: Parent类有一个ID(ParentOfStudentsList)的整数集合属性,同样,Student类有一个整数集合属性来保存父项的所有ID,与(StudentOfParentsList)相关联,这样做可以让你有一对多和多对一的关系家长和学生之间。
注意:在Parent和Student中派生Person类。我希望这个解决方案适合你。