【问题标题】:How to use dynamic DbSet in Entity Framework?如何在实体框架中使用动态 DbSet?
【发布时间】:2016-12-21 13:07:36
【问题描述】:

能否请您告诉我如何根据字符串变量选择 DbSet?我有以下内容:

public class DataContext : DbContext
{
    public DataContext() : base("myDb") { }

    public DbSet<Entry> RurEntries { get; set; }
    public DbSet<Entry> UsdEntries { get; set; }
    public DbSet<Entry> EurEntries { get; set; }
}

每种货币有 3 个表格:Rur,Usd,Eur。都具有相同的结构。 有一个名为 CurrentCurrency 的字符串变量,它是从 UI 更改的,可能是 3 种货币之一。在我之前没有实体框架的代码中,我有使用纯 sql 读取 db 的代码,类似于:

string sqlQuery = "Select * from " + CurrentCurrency 

现在我决定用 Entity Framework 重写代码并遇到了这个问题。任何答案将不胜感激。提前致谢。

【问题讨论】:

  • 为什么不给表引入一个标志而不是创建三个表呢?
  • 你已经尝试过哪些失败了?
  • 所有 3 个表都有 unique_id 字段,这是我从另一个软件收到的。我在该列上使用了唯一标志,如果我将所有条目放在同一个表中可能会出现问题

标签: c# entity-framework


【解决方案1】:

您只需打开 CurrentCurrency 字符串即可设置所需的值:

 var db = new DataContext();
        var CurrentCurrency = "RUR";
        DbSet<Entry> set = null;
        switch (CurrentCurrency) {
            case "RUR":
                set = db.RurEntries;
            break;
            case "EUR":
                set = db.EurEntries;
            break;
            case "USD":
                set = db.UsdEntries;
            break;
            default:
                throw new Exception();
        }
        var res = set.ToList();

【讨论】:

  • 正是我需要的。谢谢。
  • 正如@CodeCaster 写的那样,这是行不通的,因为我只能在每个 DbContext 中使用 DbSet 中的实体类 T。最后不得不向我的班级介绍货币领域。
  • @Smiley 我认为如果你使用继承应该可以工作,而 Entry 只是一个抽象基类。无论如何,CodeCaster 建议的解决方案似乎更直接。
【解决方案2】:

对于每个 DbContext,您只能在 DbSet&lt;T&gt; 中使用实体类 T。你的代码不会运行。另见Entity Framework 6 Creating Two table from the same entity object

鉴于您的评论:

所有 3 个表都有 unique_id 字段,这是我从另一个软件收到的。我在该列上使用了唯一标志,如果我将所有条目放在同一个表中可能会出现问题

您只需要一个复合主键,由 Currency 和 ExternalId 组成,如 Composite Key with EF 4.1 Code First 中所述:

public class Entry
{
    [Key]
    [Column(Order = 0)]
    public string Currency { get; set; }

    [Key]
    [Column(Order = 1)]
    public string ExternalId { get; set; }
}

然后您可以像这样读取“EUR”行:

var eurRows = dbContext.Entries.Where(e => e.Currency == "EUR");

【讨论】:

    【解决方案3】:

    您可以在实体框架中执行原始 SQL 查询。像这样:

    var curs = context.Database.SqlQuery<Entry>("Select * from " + CurrentCurrency").ToList();
    

    您还可以使其更简洁并创建一个存储过程,在其中发送一个参数并基于该参数执行SELECT 语句。然后使用实体框架,调用该过程并将结果映射到List&lt;Entry&gt;

    但是,正如我在 cmets 中所说,我个人更喜欢只有一张带有 CurrenyCode 列的表。而不是拥有 3 个具有完全相同结构但具有不同数据的表。然后可以这样查询:

    var curs = var curs = context.Currencies.Where(x=> x.CurrencyCode = CurrentCurrency)
                                            .ToList();
    

    【讨论】:

      猜你喜欢
      • 2013-04-10
      • 2011-07-15
      • 1970-01-01
      • 1970-01-01
      • 2013-02-10
      • 2014-04-28
      • 1970-01-01
      • 1970-01-01
      • 2011-06-21
      相关资源
      最近更新 更多