Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架-在已保存父实例时创建子类的实例_C#_Entity Framework - Fatal编程技术网

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去认为一个对象实际上是另一种类型之外。我发现,通常当我最终像那样与框架抗争时,我做错了什么。