如何在实体框架中使用动态DbSet

本文关键字:动态 DbSet 框架 实体 | 更新日期: 2023-09-27 18:02: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,如:

string sqlQuery = "Select * from " + CurrentCurrency 

现在我决定用实体框架重写代码,并面临这个问题。任何答案都将不胜感激。

如何在实体框架中使用动态DbSet

你可以简单地打开你的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();

每个DbContext只能在DbSet<T>中使用一次实体类T。您的代码将无法运行。参见实体框架6从同一个实体对象创建两个表。

考虑到你的评论:

所有3个表有unique_id字段,我从另一个软件接收。我在该列上使用了唯一标志,如果我将所有条目放入同一个表

,可能会出现问题。

您只需要一个复合主键,由Currency和ExternalId组成,正如复合键与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");

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

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

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

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

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