实体框架-当父实例已经保存时,创建子类的实例

本文关键字:实例 创建 子类 保存 框架 实体 | 更新日期: 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就不会试图使用它们来生成列。