实体框架-当父实例已经保存时,创建子类的实例
本文关键字:实例 创建 子类 保存 框架 实体 | 更新日期: 2023-09-27 18:25:00
考虑以下类:
[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();
组织可以在任何时候创建,作为销售周期的一部分。在某个时间点,组织可能会成为客户。因此,我需要能够为数据模型中已经存在的组织创建一个Customer实例。
有正确/简单的方法吗?
无法尝试将组织强制转换为客户,因为检索到的实体是无法强制转换的代理。我可以使用将客户的密钥直接添加到数据库中
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的新Organization实例。
我是不是错过了一些显而易见的东西?
对我来说,这听起来像是一个体系结构问题。我不把Customer
作为Organization
的子类,而是把它作为一个"附加表"。这样,所有内容都在Organization表中有一个条目,Customer中的一个可选条目有一个指向Organization的外键。
您可以通过检查组织的.Customer
属性来查看该组织是否是客户,并像SomeOrg.Customer.SomeCustomerProperty
一样从中访问数据,或者是否使用新的C#功能SomeOrg?.Customer.SomeCustomerProperty
。
当您想将一个组织转换为客户时,只需为他们添加一个"客户"行。
如果真的想要,可以向Customer添加一些"包装器"属性,这些属性只是对Customer实例的调用,如下所示。
public string SomeCustomerProperty
{
get
{
return this?.Customer.SomeCustomerProperty;
}
}
它们应该应用NotMapped属性,这样EF就不会试图使用它们来生成列。