SqlQuery针对未知(在编译时)类型

时间:2012-10-29 18:46:08

标签: asp.net-mvc entity-framework

我有一个应用程序,我有一个要执行的数据库查询列表。

我知道可以这样做:

var results = _db.Contacts.SqlQuery( sQuery );

并且喜欢:

var results = _db.Database.SqlQuery<Contacts>( sQuery );

但在我的情况下,我只使用元数据。我怎么能这样做:

string sBaseType = "Contacts";
var results = _db.Database.SqlQuery<sBaseType>( sQuery );

我在<object>取得了一些成功...它返回了我预期的所有行,但它不是一个非常有用的形式。什么是处理这种动态查询的最佳方式?

编辑 - 我希望找到的是某种机制,就像这样:

var results = _db.Database[sBaseType].SqlQuery( sQuery );

这样我就可以避免看起来像这样的结构:

if (sBaseType == "Contacts") {
    var results = _db.Contacts.SqlQuery( sQuery );
} else if  (sBaseType == "Buildings") {
    var results = _db.Buildings.SqlQuery( sQuery );
} else if  (sBaseType == "Rooms") {
    var results = _db.Rooms.SqlQuery( sQuery );
} else if  (sBaseType == "Equipment") {
    var results = _db.Equipment.SqlQuery( sQuery );
}

我不需要任何特别花哨的东西......我只是希望能够节省构建一个100+元素if-elseif块......

2 个答案:

答案 0 :(得分:1)

您可以尝试某种类型解析字典。

public abstract class MetadataQuery
{
  public abstract string Type { get; }
  public abstract string QueryString { get; }
}

public class ContactsQuery : MetadataQuery
{
  public override string Type { get { return "Contact"; } }
  public override string QueryString { get { return "select * from Contacts where is_deleted = 0"; } }
}

为每种类型编写查询。

接下来,编译一个类型列表。大多数IoC容器都可以为您完成此操作。使用Ninject,你会做这样的事情。而动态类型使这更加微不足道。

kernel.Bind<MetadataQuery>().To<ContactsQuery>();
// keep doing this for all of your metadata queries.

最后,当您准备好实际使用查询时。

public class MyClass
{
  private readonly IDbConnection db;
  private readonly IDictionary<string, MetadataQuery> queries;

  public MyClass(IDbConnection db, IEnumerable<MetadataQuery> queries)
  {
    this.db = db;
    this.queries = queries.ToDictionary(q => q.Type);
  }

  public IEnumerable<dynamic> ExecuteSQL(string type)
  {
    var query = queries[type];
    var result = db.Query(query.QueryString);
    return result;
  }
}

如果您绝对必须拥有非动态类型,那么您需要查看MakeGenericType,但这不会那么容易。

答案 1 :(得分:1)

这似乎解决了我的主要问题::

string sQuery = vo.objReport.sQuery;
object[] aParams = {} ;  //loaded through some other, related, process...

var tt = Type.GetType("MyProject.DAL." + vo.objReport.sBaseView);
var result =_db.Database.SqlQuery(tt, sQuery, aParams);

给定关于要运行的查询的大量元数据,它能够以可用的格式执行查询并返回数据。