【问题标题】:Entity Framework - Conditionally pull data from a primary table and a history table in one query实体框架 - 在一个查询中有条件地从主表和历史表中提取数据
【发布时间】:2012-04-24 20:03:11
【问题描述】:

我在 SQL Server 数据库中定义了以下 2 个表:

  CREATE TABLE [dbo].[FinancialItem](
    [Id][bigint] identity(1,1) NOT NULL,
    [TranId] [int] NOT NULL,
    [Installment][int] NOT NULL,
    [Amount][decimal](16,2) NOT NULL
   CONSTRAINT [FinancialItem0] PRIMARY KEY
   (
     [Id] ASC
   )

  CREATE TABLE [dbo].[FinancialItemHistory](
    [Id][bigint] NOT NULL,
    [TranId] [int] NOT NULL,
    [Installment][int] NOT NULL,
    [Amount][decimal](16,2) NOT NULL
   CONSTRAINT [FinancialItemHistory0] PRIMARY KEY
   (
     [Id] ASC
   )

我正在使用带有 POCO 实体的 Entity Framework 4.x。

实体框架代码不会将任何数据写入数据库,它只是用于读取另一个服务创建的数据。如果可能的话,我想做的是让一个实体代表这两个表。 FinancialItem 和 FinancialItemHistory 表具有相同的结构。当一个 FinancialItem 得到还清时,记录从 FinancialItem 表移动到 FinancialItemHistory 表(它保持相同的 Id)。如果我包括已付清的项目,实体框架中有没有办法有条件地提取 FinancialItemHistory 记录?我是否应该在数据库中创建一个本质上执行此操作的视图:

SELECT Id, TranId, Installment, Amount, 0 IsHistorical
FROM FinancialItem
UNION ALL
SELECT Id, TranId, Installment, Amount, 1 IsHistorical
FROM FinancialItemHistory

如果可能,我想避免使用视图,因为很多时候我只想拉出驻留在 FinancialItem 表中的未付款项。我尝试让两个实体派生自同一个接口 (IFinancialItem),然后让 Entity Framework 查询该接口,但似乎 Entity Framework 不支持映射到 IQueryable 上下文中的复杂类型。

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

    在实体框架中,您使用Concat 方法执行union all。如果你想联合两种不同的类型,你需要先将它们都转换成一个通用的类型,如下所示:

    var table1 = ...;
    var table1 = ...;
    var unionAll = table1.Select(x => new { x.ID, ... }).Concat(table2.Select(x => new { x.ID, ... }));
    

    【讨论】:

    • 对,但这不是意味着 FinancialItemHistory 和 FinancialItem 属于同一类型吗?
    • 如果我需要在查询中定义一个 WHERE 子句,然后过滤 FinancialItem 和 FinancialItemHistory 怎么办?如果不将所有表数据全部放入内存,然后进行类型转换,然后进行过滤,这是否可能?
    • 只要把 where 放在最后。 SQL Server 会将谓词下推到基表。 SQL Servers 查询优化器很厉害。
    • 啊,我明白了,问题是我试图使用通用接口 (IFinancialItem) 并且正在这样做:table1.Select(x => new FinancialItem { x.Id, ... }作为 IFinancialItem).Concat(table2.Select(x => new FinancialItem { x.Id, ... } 作为 IFinancialItem));实体框架不支持我在那个时间点尝试转换为界面。我将使用您的建议并连接一个具体类型并让 SQL 解决。谢谢!
    猜你喜欢
    • 2020-08-10
    • 2019-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 2015-02-14
    相关资源
    最近更新 更多