C# 实体框架-在已保存父实例时创建子类的实例
考虑以下类别:C# 实体框架-在已保存父实例时创建子类的实例,c#,entity-framework,C#,Entity Framework,考虑以下类别: [Table("Organization", Schema = "dbo")] public class Organization { [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid OrganizationId { get; set; } [StringLength(100)] public string Name { get; set; } /
[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的客户附加到模型,甚至尝试在System.Data.Entity.Migrations中使用AddOrUpdate函数,但EF始终使用唯一Id创建新的组织实例
我是否遗漏了一些明显的东西?这听起来像是一个架构问题。我将把
Customer
作为Organization
的子类,而不是将其作为“附加表”。这样,所有内容在组织表中都有一个条目,在Customer中有一个可选条目,该条目的外键指向组织
您可以通过检查组织的.customer
属性来查看组织是否为客户,并从中访问数据,如SomeOrg.customer.SomeCustomerProperty
,或者如果使用新的C功能,SomeOrg?.customer.SomeCustomerProperty
当您想将组织转换为客户时,只需为其添加一个客户行
如果您真的愿意,您可以向Customer添加一些“包装器”属性,这些属性只是对Customer实例的调用,如下所示
public string SomeCustomerProperty
{
get
{
return this?.Customer.SomeCustomerProperty;
}
}
这些列应具有应用于它们的属性,以便EF不会尝试使用它们生成列。客户是组织还是组织有客户?is-a关系在这里没有意义,但has-a有意义。客户永远是一个组织。在一个纯粹的通用解决方案中,一个组织可能也有客户,但我目前不尝试对此进行建模。您应该能够在一个事务中删除该组织并添加客户。但是组织机构的外键呢?您将如何处理这个问题?我不喜欢在组织中实现与客户有关的任何内容,因为这会破坏基本的对象继承。我可以看到创建一个客户类,将组织封装为一个可能的解决方案。然而,这是一种架构上的折衷。EF完美地映射了继承解决方案的表和数据。如果有必要打破继承,这似乎是一件很遗憾的事情。很好,除了你需要“欺骗”EF去认为一个对象实际上是另一种类型之外。我发现,通常当我最终像那样与框架抗争时,我做错了什么。