使用LINQ到SQL的动态查询

本文关键字:动态 查询 SQL LINQ 使用 | 更新日期: 2023-09-27 17:50:58

我需要弄清楚是否有可能动态地使用LINQ构建查询,动态地选择要执行查询的表。

这是我要做的一个例子:

//Not working,just for example
public List<dynamic> _getGenericList(String tableName)
    {
        var l = from a in db.//I need to use here tableName
                  select a;
        return l.ToList<dynamic>();
    }

有办法使这成为可能吗?

使用LINQ到SQL的动态查询

如果查询这么简单,您可以动态创建一个标准sql语句并执行它,这是最简单的方法,而不使用处理器繁重的反射和复杂的代码?

var query = "SELECT * FROM " + tableName;
var res = context.ExecuteQuery<dynamic>(query).ToList();

我已经找到了一种方法,但是我不确定是否要使用这段代码。如果您有一个包含两个表的DataContext:

PrimaryTable 
    ID,
    FirstValue,
    SecondValue
SecondaryTable
    ID,
    FirstSecondaryValue

您可以使用以下DataHelper类:

class DataHelper
{
    public MyDatabaseDataContext db = new MyDatabaseDataContext();
    List<dynamic> GetDynamicList<T>() where T : class
    {
        System.Data.Linq.Table<T> table = db.GetTable<T>();
        var result = from a in table select a;
        return result.ToList<dynamic>();
    }
    public List<dynamic> GetWhatIWant(string tableName)
    {
        Type myClass = Type.GetType("DynamicLinqToSql." + tableName);
        MethodInfo method = typeof(DataHelper).GetMethod("GetDynamicList", BindingFlags.NonPublic | BindingFlags.Instance);
        method = method.MakeGenericMethod(myClass);
        return (List<dynamic>)method.Invoke(this, null);
    }
}

然后您可以创建DataHelper的一个实例,并调用GetWhatIWant方法,传入表名。

var dataHelper = new DataHelper();
List<dynamic> myFirstList = dataHelper.GetWhatIWant("PrimaryTable");
for (int i = 0; i < 5 && i < myFirstList.Count; i++)
{
    System.Console.WriteLine(String.Format("{0} - {1}", myFirstList[i].FirstValue.ToString(),  myFirstList[i].SecondValue.ToString()));
}
List<dynamic> mySecondList = dataHelper.GetWhatIWant("SecondaryTable");
for (int i = 0; i < 5 && i < mySecondList.Count; i++)
{
    System.Console.WriteLine(mySecondList[i].FirstSecondaryValue.ToString());
}
System.Console.ReadKey();

我知道这是旧的,但如果你在这里寻找像我一样的答案,那么也许这将有所帮助。我直接使用。net ObjectContext而不是DataContext数据源。如果你使用的是DataContext版本,那么你可以简单地(我希望)使用queryResults = myGlobalContext.ExecuteQuery<dbGenericData>(query).ToList();代替,我很确定它会以同样的方式工作。

如果你有像

这样的命名和设计标准,你的表将更容易处理。
  • 表的ID字段总是X类型(INT, GUID等)
  • ID字段总是命名为tableNameID,即带有ID标签的"表名"。
  • ,

这将允许您通过简单地将'ID'字符串附加到表名上轻松构建ID字段,并且允许您在需要时使用可靠的CAST。

说到CAST,您会在查询字符串中注意到一个。您将需要使用CAST修改SQL字符串的使用,更改字段长度,如我的nvarChar(50)示例等,以克服从数据库获取各种类型的数据的问题。

最后注意:在查询字符串中,您将看到我使用'AS'关键字将DB字段转换为新名称。我将'tableIDField'转换为名称'id',并将' requestdfield '转换为名称'dbData'。这允许系统将DB中的重命名字段匹配到我们转储数据的STRUCT对象容器中。这允许您构建通用容器来保存返回的数据,而不必担心与DB字段名称匹配。

我不是这方面的专家,但我希望这能帮助到一些人。

private void testMethod(string requestedField, string tableName)
{
    var tableIDField = tableName + "ID";
    var query = "select " + tableIDField + " as id, CAST(" + requestedField + "as nvarchar(50)) as dbData from " + tableName;
    List<dbGenericData> queryResults = null;
    try
    {
        queryResults = myGlobalContext.ExecuteStoreQuery<dbGenericData>(query).ToList();
    }
    catch (Exception ex)
    {
        //Simply ignore any exceptions.  
        //These will need examined to determine best solution to unexpected results.
    }
}
private struct dbGenericData
{
    public dbGenericData(int id, string dbData)
    {
        this = new dbGenericData();
        ID = id;
        DBData = dbData;
    }
    public int ID { get; set; }
    public string DBData { get; set; }
}

您可以使用泛型方法并使用基于T返回DbSetdb.Set<T>

var esql = "select t from TypeName as t"var q = db.CreateQuery(esql);之前