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

时间:2014-09-05 16:57:57

标签: c# sql entity-framework entity-framework-6

我的场景

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

在我的代码中 - 改名为保护无辜的名字:) - 我有:

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

问题

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

澄清:

  • 我提到的“视图”是一个数据库视图,它从表中读取但以不同方式解释优先级。
    • 所以,在这种情况下,我们只想从视野中拉出来。
  • 数据库视图和数据库表具有相同的字段。
  • 我正试图找到一种避免使用ClassAClassB的方法,两者都具有相同的属性,因此我可以从视图中拉出一个,从表中拉出另一个。
  • 我指的只是阅读数据。这里没有更新的期望。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,您可以使用SqlQuery从查看生成的查询中加载。

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

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

<强> PS

如果视图名称的格式类似于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);