考虑以下课程:
[Table("Organization", Schema = "dbo")]
public class Organization
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid OrganizationId { get; set; }
[StringLength(100)]
public string Name { get; set; }
/* Other organization attributes */
}
[Table("Customer", Schema = "dbo")]
public class Customer : Organization
{
/* Extends organization for customer specific details */
}
Organization o = new Organization { Name = "worlddata.online" };
db.Organization.Add(o);
db.SaveChanges();
可以随时创建组织作为销售周期的一部分。在某个时间点,组织可能成为客户。因此,我需要能够为数据模型中已存在的组织创建客户实例。
有没有正确/简单的方法来做到这一点?
尝试将组织强制转换为客户是不可能的,因为检索到的实体是无法转换的代理。我可以使用以下方法将客户的密钥直接添加到数据库中:
db.Database.ExecuteSqlCommand("INSERT [dbo].[Customer] ([OrganizationId]) VALUES('" + o.OrganizationId.ToString() + "')");
但是如果已经加载了父组织,当我尝试访问客户时会出现错误:例如电话
Customer cu = (from x in db.Customer where x.Name == "worlddata.online" select x).FirstOrDefault();
将生成:
'DatabaseContext.Organization' must have unique primary keys. However, an instance of type 'overwatch.data.Customer' and an instance of type 'overwatch.data.Organization' both have the same primary key value
我尝试将具有正确OrganizationId的Customer附加到模型,我甚至尝试在System.Data.Entity.Migrations中使用AddOrUpdate函数,但EF总是创建一个具有唯一ID的新组织实例。
我错过了一些明显的东西吗?
答案 0 :(得分:1)
这听起来像是一个建筑问题。我没有将Customer
作为Organization
的子类,而是将其作为一个附加表"。这样,组织表中的所有条目都有一个条目,在Customer中有一个可选条目,该条目具有指向组织的外键。
您可以通过查看组织的.Customer
属性来查看组织是否是客户,并从SomeOrg.Customer.SomeCustomerProperty
访问数据,或者如果使用新的C#功能, SomeOrg?.Customer.SomeCustomerProperty
。
如果要将组织转换为客户,只需为其添加“客户”行即可。
如果真的想要,你可以添加一些"包装"客户的属性,只是调用Customer实例,如下所示。
public string SomeCustomerProperty
{
get
{
return this?.Customer.SomeCustomerProperty;
}
}
这些属性应该应用NotMapped属性,以便EF不会尝试使用它们来生成列。