.net 代码优先TPT继承-如何提供外键而不是EF为我创建父行?
我有一个基本的继承层次结构,如下所示:.net 代码优先TPT继承-如何提供外键而不是EF为我创建父行?,.net,entity-framework,ef-code-first,.net,Entity Framework,Ef Code First,我有一个基本的继承层次结构,如下所示: public class Parent { public int ParentID {get; set;} public string SomeOtherProperty {get; set;} }; public class Child : Parent { public string SomeChildProperty {get; set;} }; 我有多个子类,我有一个Auditor对象,它有一个基于父类的接口,允许我以
public class Parent
{
public int ParentID {get; set;}
public string SomeOtherProperty {get; set;}
};
public class Child : Parent
{
public string SomeChildProperty {get; set;}
};
我有多个子类,我有一个Auditor对象,它有一个基于父类的接口,允许我以通用方式写入数据库,如下所示
public class Auditor
{
public void WriteObject(Parent p)
{
using (MyDbContext context = new Context)
{
context.Parents.Add(p);
context.SaveChanges();
}
}
}
所以我可以像这样使用审核员
auditor.WriteObject(new Child1());
auditor.WriteObject(new Child2());
等等,等等,每当我写一个子对象时,EF就会在DB中为我创建父行
我遇到的问题是,在某些情况下(可能有10%的时间),我希望将子记录写入数据库并将其链接到现有的父行,即,我希望提供外键
我试过类似的东西
Child1 child = new Child();
child1.ParentID = existingID;
auditor.WriteObject(child);
但是EF忽略了我提供的外键,并为我创建了一个新的父记录
有没有办法让EF理解,由于父ID已经存在于我试图写入的子对象上,它不需要插入父行?根据您的描述,我有点困惑,但我会尝试回答我认为您可能指的场景: 选项1:我想这就是您所追求的:您正在创建父类的对象。稍后,您将获得更多信息,并希望将它们“向下转换”到适当的子类。这在EF的情况下是不可能的。一旦对象被创建为特定类型,它就必须保留该类型。在您的情况下,选项如下:
我创建了一个ID=1的新卷毛狗,我只会有一组ID=1的记录,在动物、狗和卷毛狗中各有一行,嗨,Matthew。我想要的是选项2。我知道我可以按照你的建议去做,但是我很犹豫。我正在尝试保持父类的通用性,并允许应用程序通过子类来扩展它。如果我向父类添加子类集合,父类就不再是通用的。你的评论实际上让我认为你仍然是通用的谈到选项1(或者可能是两者的混合)。您的代码让我想到的是,在某些情况下,父对象已经存在,并且您正在将其“扩展”为子类型对象(尝试设置父ID)。在您的情况下,父对象是否可以是抽象类?如果目的是允许某人稍后加载父对象,将其扩展为子类型,添加详细信息,然后重新保存,则需要遵循选项1中的方法。您是对的……我键入得太快,意思是说选项1。我无法删除与父对象对应的数据库行ype实例,因为该行可能是其他子类型的父行。这意味着父行是通过保存另一个子类型创建的,我希望使用此子类型锁定它。可能我唯一的选择是返回到一个良好的旧ADO.NET存储过程:)我更新了我的答案-我认为你还不需要放弃这场斗争,我只是认为你没有意识到,虽然你可能有一个TPT解决方案,但你目前正试图滥用它来完成这项任务。:)嗨,Matthew。在阅读了您的更新并自己做了更多工作之后,我得出了相同的结论——我在这里错误地使用了TPT继承。我重新编写代码,只使用标准的一对多外键关系。谢谢你帮我度过难关!为什么孩子继承父母?孩子不应该有父母财产吗?嗨,Usr。是的,子级可以有父属性,但这将建立外键关系,而不是继承关系。
Child1 child = new Child();
Parent p = _context.Parents.Find(search based on ID)
p.Children.Add(child);
auditor.WriteObject(p);