在我的应用程序中,一个人可以拥有一个由神提供给他们的GuardianSpirit。最初他们没有。 GuardianSpirit仅与Person相关,因此必须已创建该人。
这些是我的课程:
public class Person {
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public virtual GuardianSpirit GuardianSpirit { get; set; }
}
public class GuardianSpirit {
[Key, ForeignKey("Person")]
public int PersonID { get; set; }
public string Name { get; set; }
public virtual Person Person { get; set; }
}
如果没有与Person关联的GuardianSpirit,则人员列表会显示创建按钮。当具有“上帝”角色的用户点击时,它会显示创建该人的GuardianSpirit的表单。这是一个screenshot。
如何传递Person的id来创建它? (它将与其所有者具有相同的ID)
谢谢!
答案 0 :(得分:2)
在1:0..1
关联中,可选实体同时拥有作为外键的主键是正常的。这是关系数据库可以做的最好的事情,以保证关联的两端完全属于彼此。
您的类正确实现了此模式:GuardianSpirit
是可选(或依赖)实体,Person
是独立的(或主体)实体。
结果是可选实体无法自由选择/生成自己的主键。你必须在你的代码中设置它。有两种方法可以做到这一点:
Person
的ID:newGuardianSpirit.PersonId = person.Id
。Person
个对象:person.GuardianSpirit = newGuardianSpirit
。第一个选项是可能的,因为GuardianSpirit.PersonId
不是标识列(当EF创建数据库时),因此数据库不会生成它的值。
答案 1 :(得分:2)
只需在新Person
上设置GuardianSpirit
即可。但请确保在DbSet上使用Create()
方法,以便获得代理对象。这样设置Person
PersonID
时也会自动设置。请参阅有关导航属性的文档on msdn。
var person = dbcontext.Person.Create();
person.FirstName = "Bob";
person.LastName = "Roberts";
person.Age = 24;
dbcontext.Person.Add(person);
// dbcontext.SaveChanges(); // person will have a new ID if it is saved here
var guardian = dbcontext.GuardianSpirit.Create();
guardian.Name = "Luke";
guardian.Person = person;
dbcontext.GuardianSpirit.Add(guardian); // If the person was saved then the PersonID should now also be set
dbcontext.SaveChanges();
答案 2 :(得分:0)
数据库设计不正确,因为GuardianSpirit类中的PersonID既是外键也是主键。
问题在于,现在你不能用正确的人的身份来创造一个守护精神,因为它是GuardianSpirit实体的主要钥匙。
应该是:
public class Person {
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public virtual GuardianSpirit GuardianSpirit { get; set; }
}
public class GuardianSpirit {
[ForeignKey("Person")]
[DatabaseGenerated( DatabaseGeneratedOption.None )]
public int PersonID { get; set; }
public string Name { get; set; }
public virtual Person Person { get; set; }
}
然后,您可以创建新的GuardianSpirit实例,为其命名并设置您希望分配的Person的PersonID。然后,您可以使用Entity Framework将此对象添加到数据库并保存更改。
//here read person id
var personId = 5;
var guardianSpirit = new GuardianSpirit()
{
Name = "Gabriel",
PersonID = personId
};
//_context is DbContext
_context.GuardianSpirirts.AddObject(guardianSpirit);
_context.SaveChanges();