Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.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
Inheritance 实体框架-继承-与子对象的零对一关系,如何映射?(流畅的API)_Inheritance_Entity Framework 4_Entity Relationship_Fluent Interface - Fatal编程技术网

Inheritance 实体框架-继承-与子对象的零对一关系,如何映射?(流畅的API)

Inheritance 实体框架-继承-与子对象的零对一关系,如何映射?(流畅的API),inheritance,entity-framework-4,entity-relationship,fluent-interface,Inheritance,Entity Framework 4,Entity Relationship,Fluent Interface,我有一个继承层次结构,其中Action是ActionCompleted和ActionCancelled的父级。订单类有一个0:1的ActionCompleted和ActionCancelled。我尝试过TPH和TPT(甚至尝试过edmx),但无法让实体理解订单和子操作之间的关系,请建议如何映射 //Classes public class Order { public int OrderId { get; set; } public strin

我有一个继承层次结构,其中Action是ActionCompleted和ActionCancelled的父级。订单类有一个0:1的ActionCompleted和ActionCancelled。我尝试过TPH和TPT(甚至尝试过edmx),但无法让实体理解订单和子操作之间的关系,请建议如何映射

//Classes
    public class Order
    {
        public   int OrderId { get; set; }
        public string Name { get; set; }
        public   ActionCompleted ACO { get; set; }
        public ActionCancelled ACA { get; set; }

    }

public class Action
{
    public   int ActionID { get; set; }
    public   DateTime ActionDT { get; set; }
    public   Order Order { get; set; }
}

public class ActionCompleted : Action
{

}
public class ActionCancelled : Action
{
    public int CancelledByPhysician { get; set; }
}
//映射

public class EDISContext:DbContext
{
    public EDISContext()
        : base("EDISContext")
    { }


    public DbSet<Order> Orders { get; set; }

    public DbSet<Action> Actions { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Order>().ToTable("Orders");

        modelBuilder.Entity<Action>().HasKey(a => a.ActionID);

        modelBuilder.Entity<Action>().Map(m => m.ToTable("Actions"))
                                              .Map<ActionCompleted>(m => m.ToTable("ActionCompleted"))
                                              .Map<ActionCancelled>(m => m.ToTable("ActionCancelled"));

        //modelBuilder.Entity<Action>().HasRequired(a => a.Order).WithOptional().Map(m => m.MapKey("DiagOrderId"));
        modelBuilder.Entity<ActionCompleted>().HasRequired(a => a.Order).WithOptional().Map(m => m.MapKey("DiagOrderId"));
        modelBuilder.Entity<ActionCancelled>().HasRequired(a => a.Order).WithOptional().Map(m => m.MapKey("DiagOrderId"));

    }
数据库表的脚本:

CREATE TABLE [dbo].[Orders](
    [OrderId] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NULL,
) ON [PRIMARY]

CREATE TABLE [dbo].[Actions](
    [ActionID] [int] IDENTITY(1,1) NOT NULL,
    [ActionDT] [datetime] NOT NULL,
    [DiagOrderID] [int] NULL,
) ON [PRIMARY]

CREATE TABLE [dbo].[ActionCompleted](
    [ACID] [int] IDENTITY(1,1) NOT NULL,
    [ActionID] [int] NOT NULL,
) ON [PRIMARY]

CREATE TABLE [dbo].[ActionCancelled](
    [ACAID] [int] IDENTITY(1,1) NOT NULL,
    [ActionID] [int] NOT NULL,
    [CancelledByPhysician] [int] NULL,
 ) ON [PRIMARY]

首先使用代码时,至少尝试让EF为您创建数据库总是很有用的-这是默认行为(将查找名为.\SQLEXPRESS的SQL Server本地实例)。如果您手动创建数据库并希望控制列名(这似乎正在发生),则需要使用fluent API指定列名。请参阅和以获取一些示例,这些示例应涵盖您遇到的困难

仅供参考,您创建的数据库将具有以下表和列名:

CREATE TABLE [dbo].[ActionCancelled](
    [ActionID] [int] NOT NULL,
    [CancelledByPhysician] [int] NOT NULL,
PRIMARY KEY CLUSTERED ( [ActionID] ASC )
)

CREATE TABLE [dbo].[ActionCompleted](
    [ActionID] [int] NOT NULL,
PRIMARY KEY CLUSTERED ( [ActionID] ASC )
)

CREATE TABLE [dbo].[Actions](
    [ActionID] [int] IDENTITY(1,1) NOT NULL,
    [ActionDT] [datetime] NOT NULL,
    [Order_OrderId] [int] NULL,
PRIMARY KEY CLUSTERED ( [ActionID] ASC )
)

CREATE TABLE [dbo].[Orders](
    [OrderId] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](max) NULL,
    [ACO_ActionID] [int] NULL,
    [ACA_ActionID] [int] NULL,
PRIMARY KEY CLUSTERED ( [OrderId] ASC )
)

如果您坚持自己创建和维护数据库,我建议您尝试使用数据库优先工作流,而不是代码优先。从数据库创建实体数据模型,然后生成POCO。这将使您的生活更加轻松,尤其是在更改数据库模式的情况下


为了让EDM理解表关系,必须在数据库中设置它们。我不知道你是否读过,因为你没有粘贴任何创建外键的脚本,但是VS在理解正确定义的模式时应该没有任何问题。

我知道我有点不耐烦,但我想知道是否正在使用实体框架?也许我需要开始看Nhibernate。你能澄清一下“无法让实体理解订单和子动作之间的关系”是什么意思吗?如果创建命令和操作并尝试将它们保存到数据库中,会发生什么?我将您的代码复制并粘贴到一个控制台应用程序中,它运行良好。我认为它会引发类似以下的异常:无效列名“ActionCompleted\u ActionId”。\r\n无效列名“ActionCompleted\u ActionId”--只是为了澄清,Orders表与Actions表相关,OrderId作为外键存储在Action表中。(orders表中没有引用键,这就是您创建表的方式吗?——如果您不介意,请发布您创建的表的脚本,我将再次尝试我的代码。我将很快发布我的表的脚本。另一件事:我在添加操作时使用现有的顺序,我设置了它们的顺序属性,请参见下面的:EDISContext db=new EDISContext();var ord1=db.Orders.FirstOrDefault(o=>o.OrderId==1);OrderActionEntered ae1=新OrderActionEntered();ae1.ActionDoneBy=1;ae1.ActionDT=DateTime.Now;ae1.订单=订单1;db.OrderActions.Add(ae1);db.SaveChanges();我不明白为什么我要给那些专栏。如果我正在查找ActionCompleted属性,则可以通过转到Actions表并连接到ActionCompleted来访问这些属性。我甚至尝试了TPH映射,但也没有成功,同样的错误。我看到的所有示例最终都以某种形式的集合属性与父类建立了关系。但对我来说,我正在寻找的解决方案看起来很自然,而且使用自定义数据库编码很容易实现。现在我要试试Nhibernate,看看我在那里会不会有好运。当我将ActionId存储在orders表中时,为什么我要将OrderId存储在action表中作为引用键,似乎对象世界的双向关系被推到了关系世界中。每个表中都有冗余的唯一ID。如果列名与属性名不相同,我使用fluentapi表示相同。我将尝试在没有order的情况下再次测试这段代码,看看它是否仍然有效。如果order类中有15个action类型的属性该怎么办。顺序应该是零对一,我知道我可以使用一组动作从数据库中提取,并在getter中编写一些逻辑来获取这些单独的属性。我不确定我是否理解你所有的问题。Re:为什么要在操作表中存储OrderId;您不必这样做,但如果不这样做,您将需要Orders中*ActionId列的索引,或者您将进行表扫描以查找给定操作的顺序。回复:15处房产;在这种情况下,Order将有15个可为null的*ActionId列。当然还有其他有效的模式表示,但是定义数据库模式的算法经过了很好的测试。EF将生成的数据库将执行类似于我可以识别的任何备选方案。我想分别创建我的POCO和DB,然后使用ORM映射它们。但是我会先尝试做DB,看看是否创建了正确的POCO。顺便说一句,在我的另一篇文章中,我甚至无法从Nhibernate那里得到这个问题的答案。
CREATE TABLE [dbo].[ActionCancelled](
    [ActionID] [int] NOT NULL,
    [CancelledByPhysician] [int] NOT NULL,
PRIMARY KEY CLUSTERED ( [ActionID] ASC )
)

CREATE TABLE [dbo].[ActionCompleted](
    [ActionID] [int] NOT NULL,
PRIMARY KEY CLUSTERED ( [ActionID] ASC )
)

CREATE TABLE [dbo].[Actions](
    [ActionID] [int] IDENTITY(1,1) NOT NULL,
    [ActionDT] [datetime] NOT NULL,
    [Order_OrderId] [int] NULL,
PRIMARY KEY CLUSTERED ( [ActionID] ASC )
)

CREATE TABLE [dbo].[Orders](
    [OrderId] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](max) NULL,
    [ACO_ActionID] [int] NULL,
    [ACA_ActionID] [int] NULL,
PRIMARY KEY CLUSTERED ( [OrderId] ASC )
)