【问题标题】:EF Core - Pulling Data From Two Identical TablesEF Core - 从两个相同的表中提取数据
【发布时间】:2020-02-17 00:44:50
【问题描述】:

TLDR:我有两个具有相同定义的表,我需要根据某个开关从一个表中提取 另一个表。

例如,假设一个包含一堆“通用”FooItem 的表和一个包含“花式”FooItem... 的表,这两个表之间的唯一区别是名称,SIMPLE_FOO 和 @987654325 @

取决于一个布尔值,比如GetFancy == true,我应该从FANCY_FOO读取,否则,SIMPLE_FOO

这在DbContext 中变得复杂。我的上下文中不能有多个DbSet<FooItem>,我不能动态地“注入”ModelBuilder.Entity<FooItem>(e => e.ToView("pickOne")) 中的表名......而且我不想复制整个 dbContext 只是为了有一个里面有不同的表名。

我确信解决方案很简单,但我只是没有看到它。感谢您提供任何帮助。

编辑:我无法更改数据库。这是一种愚蠢的做法,但他们就是这样做的,我必须忍受它。

【问题讨论】:

  • 拥有两个具有相同架构的相同表可能不是一个好方法。这应该是一个带有额外布尔字段Fancy 的表,可以将记录彼此区分开来。这样,您只需要一个 DbContext 引用,并且可以使用 LINQ 查询来获取“花式”的记录或“简单”的记录。只是我的两分钱
  • 我只是在使用我拥有的数据结构。我不会这样设计,但我无法更改数据结构 - 这个数据库已有数十年历史,不在我的授权范围内
  • 您不需要复制整个 DbContext,只需创建两个不同名称的重复实体(或从公共基类派生两个),然后拥有两个 DbSet。还是您的意思是您不想复制 DbSet?
  • docs.microsoft.com/en-us/ef/core/modeling/inheritance 我认为您想要的是 TPT(每种类型的表),但我不确定这是否已在 EF Core 中实现
  • @BryanLewis 我不知道该怎么做,你能发布答案吗?

标签: c# asp.net-core entity-framework-core dbcontext ef-core-2.2


【解决方案1】:

您的解决方案中只有两个实体,每个表一个。它们可以从基类继承,因为它们是相同的。创建包含两个表中所有字段的基类“BaseFooItem”。然后为每个变体(Simple 和 Fancy)创建一个实体类,并注释每个以匹配必要的表名;例如:

[Table("SIMPLE_FOO")]
public class SimpleFooItem: BaseFooItem {
}

如果您不想使用数据注释,也可以使用 FluentAPI 设置表名。然后为每个实体创建一个 DbSet:

    public DbSet<SimpleFooItem> SimpleFooItems { get; set; }
    public DbSet<FancyFooItem> FancyFooItems { get; set; }

然后根据条件在每个 DbSet 之间切换,例如:

if (GetFancy) {
   return dbContext.FancyFooItems.SingleOrDefault(a => a.Id == id);
} else {
   return dbContext.SimpleFooItems.SingleOrDefault(a => a.Id == id);
}

希望我能正确理解您的需求。

【讨论】:

  • 所以在 OnModelCreating 中,我只是为FancyFooItems 构建一个实体,为SimpleFooItems 构建另一个具有正确表名的实体?有没有办法重构它,使其不仅仅是复制/粘贴代码?
  • 嗯,实际的 DBSet 不在 OnModelCreating 内部,但它们都在 DbContext 类内部。如果您不想像我展示的那样使用注释,您可以使用 Fluent API 在 OnModelCreating 中配置表名。例如builder.Entity(a => a.ToTable("SIMPLE_FOO")。我想不出没有两个实体的方法。我不知道有任何方法可以进行任何动态切换。你可以使用如果您想完全绕过 EF 内容,请使用存储过程。
【解决方案2】:

在我看来,最简单的做法是利用.FromSql() 方法并使用它来选择哪个表:

var foos = GetFancy
  ? dbContext.FromSql(select * from FANCY_FOO)
  : dbContext.FromSql(select * from SIMPLE_FOO)

return foos.Where(/* etc /*)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-21
    • 2022-01-16
    • 2019-12-07
    • 1970-01-01
    • 2023-04-01
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多