将视图和表映射到EF中的相同模型?

肖恩·基林(SeanKilleen)

我的场景

  • 我有一个项目表,每个项目都有一个优先级和一些其他信息。
  • 我还有一个数据库视图,该视图从该表中选择*,但根据项目的其他某些属性替换优先级
  • 视图和表都包含完全相同的字段,只是优先级的内容发生了变化。

在我的代码中-更改名称以保护无辜的人:)-我有:

[Table("schema.Items")] //The table
public class Item
    {
      //...all of the fields that exist in both the table and the view.
    }

问题

  • 在这种情况下,有没有办法让我从视图中而不是从表中拉出,而是自然地将其映射到同一模型?如果是这样,我该怎么做?

说明:

  • 我提到的“视图”是一个数据库视图,它从表中读取但对优先级的解释不同。
    • 因此,在这种情况下,我们只想从视图中撤出。
  • 数据库视图和数据库表具有相同的字段。
  • 我试图找到一种避免ClassAClassB都具有相同属性的方法,只是我可以从视图中拉出一个,而从表中拉出另一个。
  • 我仅指读取数据。这里没有更新的期望。
尤里亚姆·钱德拉

如果我对您的理解正确,则可以使用SqlQuery加载从视图生成的查询。

var db = ...; // instance of context

var q = db.Set<ViewModel>().Where(...).ToString();
var result = db.Database.SqlQuery<TableModel>(q);

聚苯乙烯

如果视图名称具有类似的模式view_TableName,则可以使用TableModel生成查询,然后将表名称替换为视图名称。

这是一种可以实现此目的的扩展方法。

public static string GetViewSql<T>(this DbContext db, IQueryable<T> q)
    where T : class
{
    const string prefix = "view_";
    var tableName = Regex.Match(
        db.Set<T>().ToString(), 
        @"FROM (\[.*\]\.\[.*\]) AS \[Extent1\]").Groups[1].Value;
    var viewName = Regex.Replace(
        tableName, 
        @"\[.*\]\.\[(.*)\]", 
        m => m.Groups[0].Value.Replace(
            m.Groups[1].Value, prefix + m.Groups[1].Value));
    var sql = q.ToString().Replace(tableName, viewName);
    return sql;
}

用法:

var query = db.Set<TableModel>().Where(...);
var sql = db.GetViewSql(query);
var result = db.Database.SqlQuery<TableModel>(sql);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章