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

时间:2015-11-30 12:35:55

标签: 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; }
    /* 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的新组织实例。

我错过了一些明显的东西吗?

1 个答案:

答案 0 :(得分:1)

这听起来像是一个建筑问题。我没有将Customer作为Organization的子类,而是将其作为一个附加表"。这样,组织表中的所有条目都有一个条目,在Customer中有一个可选条目,该条目具有指向组织的外键。

您可以通过查看组织的.Customer属性来查看组织是否是客户,并从SomeOrg.Customer.SomeCustomerProperty访问数据,或者如果使用新的C#功能, SomeOrg?.Customer.SomeCustomerProperty

如果要将组织转换为客户,只需为其添加“客户”行即可。

如果真的想要,你可以添加一些"包装"客户的属性,只是调用Customer实例,如下所示。

public string SomeCustomerProperty 
{
    get 
    { 
        return this?.Customer.SomeCustomerProperty;
    }
}

这些属性应该应用NotMapped属性,以便EF不会尝试使用它们来生成列。

相关问题