实体框架TPC继承问题

时间:2016-06-26 07:56:03

标签: sql .net entity-framework inheritance entity-framework-6

我想在我的应用程序中使用Table Per Concrete类型继承:

public class Row {
    public int Id {get;set;}
    public string Name {get;set;}
}

public class ExtendedRow : Row {
    public int Weight {get;set;}
}

每个类都需要映射到自己的视图,ExtendedRow视图包含Row视图的所有列。

我的配置是:

    modelBuilder.Entity<Row>().Map(m => {
        m.MapInheritedProperties();
        m.ToTable("Row");
    });
    modelBuilder.Entity<ExtendedRow >().Map(m => {
        m.MapInheritedProperties();
        m.ToTable("ExtendedRow");
    });

查询ExtendedRow就好了。但是,查询Row会生成以下SQL:

SELECT 
        [Extent1].[Id] AS [Id], 
        [Extent1].[Name] AS [Name]
        FROM [dbo].[Row] AS [Extent1]
UNION ALL
SELECT 
        [Extent2].[Id] AS [Id], 
        [Extent2].[Name] AS [Name]
        FROM [dbo].[ExtendedRow] AS [Extent2]

为什么EF添加UNION ALL运营商?我该如何解决?

2 个答案:

答案 0 :(得分:1)

关于此主题的堆栈溢出有几个问题 EF以您看到的方式工作,如果您要求Base,您将收到实现Base的所有对象(即Base和派生对象)。如果您使用TPC,您将看到UNION,如果您使用TPH,您将看到EF省略了鉴别器字段上的where子句(即,它与TPC或TPH无关,结果始终相同)。 GetType不是EF规范函数,因此您无法使用它,但我已经阅读了您可以使用的EF 6.x(在您的情况下为!(m is ExtendedRow))。实际上我不知道它是否有效。

通常我不会映射Base类(即我创建一个从base派生的空类而不是映射它。)

答案 1 :(得分:0)

找到适合我的建议here

public abstract class RowBase {
    public int Id {get;set;}
    public string Name {get;set;}
}

public class Row : RowBase {
}

public class ExtendedRow : RowBase {
    public int Weight {get;set;}
}

关键是要有一个abstract类,以便EF在使用MapInheritedProperties()时不会尝试使用继承逻辑。